Search code examples
c++multithreadingsocketsepollkqueue

Can epoll or kqueue handle asynchronous additions of file descriptors to itself


If one thread (say X) is waiting on an epoll_wait() can another thread (say Y) makes a call to epoll_ctl() to register interest in file descriptor 9. Can the previous call to epoll_wait() in thread X return the file descriptor 9 added by thread Y? The initial call to epoll_wait() never returned in the middle at any point.

Now I want to compare this and ask related questions with respect to two other polling calls in operating systems. poll() and kqueue

  1. If the answer to the above question is true then is there a way to achieve similar behavior with the poll() system call?
  2. Let us assume that epoll_ctl() is thread safe and thread X can safely call epoll_ctl() and have the call to epoll_wait() return whether the file descriptor 9 is ready for I/O. The separation of the function to declare interest in the file descriptor and the function to wait is what would make this function amazing. But people often refer the kqueue and epoll as being used for the same functionality. However kqueue does not have a separate function to declare interest in getting event feedback for a descriptor. Does anybody know how kqueue can be used in a similar manner as epoll? epoll seems to be the best threadsafe option out there right now if it allows threadsafe "interest declaration"

Solution

  • From man epoll_wait:

    While one thread is blocked in a call to epoll_pwait(), it is possible for another thread to add a file descriptor to the waited-upon epoll instance. If the new file descriptor becomes ready, it will cause the epoll_wait() call to unblock.

    So epoll_wait watches for a file descriptor added while it is waiting.

    Such behavior cannot be achived by poll()/select(), as they read the set of file descriptors once, so one cannot modify the set of file descriptors which are currently polled.

    [Of course, if you pass a file descriptor created by epoll_create to poll()/select(), modifications of this file descriptor will be tracked as with epoll_wait.]