I'm migrating my project to io_uring for better performance. However, some part of the system depends on epoll being event system and not movable to io_uring (ex: database drivers, they write to socket internally and I get notification read/write events, never seeing what's written to the raw sockets). Forcing me to use epoll and io_uring together. Creating two threads, one for epoll and another for io_uring is not an option for various reasons.
My plan was to poll io_uring after epoll in my event loop, Like the following
while(keep_running) {
epoll_wait();
io_uring_peek_batch_cqe();
... // handle events
}
This turns out not viable. It's likely that there's no ongoing database activity, causing epoll_wait
block until timeout, thus all operations on io_uring waiting for the same timeout. Nor inverting the order and call io_uring_wait_cqe
any better. It's possible that there's DB traffic but nothing submitted to io_uring. Causing epoll to wait for io_uring timeout.
So far I've considered reducing the timeout. But it's not an elegant solution. It increases CPU usage and adds unnecessary latency. Is there a way to wait for epoll and io_uring at the same time? i.e. Some function that unblocks as soon as either epoll or io_uring has something to process.