Create Your Own Event Queue 80 Figure 4. 1-Edge-triggered versus level-triggered events mio doesn't, at the time of writing, support EPOLLONESHOT and uses epoll in an edge-triggered mode, which we will do as well in our example. What about waiting on epoll_wait in multiple threads? As long as we only have one Poll instance, we avoid the problems and subtleties of having multiple threads calling epoll_wait on the same epoll instance. Using level-triggered events will wake up all threads that are waiting in the epoll_wait call, causing all of them to try to handle the event (this is often referred to as the problem of the thundering heard). epoll has another flag you can set, called EPOLLEXCLUSIVE, that solves this issue. Events that are set to be edge-triggered will only wake up one of the threads blocking in epoll_wait by default and avoid this issue. Since we only use one Poll instance from a single thread, this will not be an issue for us. I know and understand that this sounds very complex. The general concept of event queues is rather simple, but the details can get a bit complex. That said, epoll is one of the most complex APIs in my experience since the API has clearly been evolving over time to adapt the original design to suit modern requirements, and there is really no easy way to actually use and understand it correctly without covering at least the topics we covered here. One word of comfort here is that both kqueue and IOCP have APIs that are easier to understand. There is also the fact that Unix has a new asynchronous I/O interface called io_uring that will be more and more and more common in the future. 