Closed dmantipov closed 3 weeks ago
basically do not wait for both cqes. You want to process each cqe as it happens.
in pseudocode:
sqe = io_uring_get_sqe(&ring);
io_uring_prep_poll_add(sqe, tfd, POLLIN);
io_uring_sqe_set_data64(sqe, 0); /* 0 to denote timer */
sqe = io_uring_get_sqe(&ring);
io_uring_prep_poll_add(sqe, sfd, POLLIN | POLLOUT);
io_uring_sqe_set_data64(sqe, 1); /* 1 to denote socket */
ret = io_uring_submit(&ring);
while (1) {
...
wait_cqe(&cqe);
if (cqe->user_data == 0) {
/* handle timer and resubmit a poll for the timer*/
} else if (cqe->user_data == 1) {
/* handle socket and resubmit a poll for the socket*/
}
io_uring_cqe_seen(&ring, cqe);
}
By the way you can make this better by: 1) use multishot poll add, which will continue posting polls until the IORING_CQE_F_MORE flag is not set (to reduce the number of submissions). 2) use proper io_uring operations on the socket. This just saves a step from poll -> op.
I have a question on using
io_uring_prep_poll_add()
and waiting for multiple events.There are two descriptors, say
tfd
andsfd
. The first one is returned bytimerfd_create()
system call, and the timer is expected to tick once a second. The second one is a socket, which is expected to do thousands reads/writes in a second. So, the simple and convenientpoll()
-based event loop may be:Using
io_uring
, it may be:What's next? The straightforward thing like:
effectively limits the rate of the (outer, i. e.
while(1)
) loop to one iteration per second (because it waits for both timer and socket events). So what's the proper way to wait and handle CQEs to be sure that 1) socket I/O is processed at the full speed and 2) the loop is never miss the timer event?