I want to add a file descriptor to an existing epoll instance but not have it wake up yet. Specifically, I would like to make sure that
EPOLLHUP are not raised. I am using
EPOLLONESHOT to wake up a single thread at a time, then
EPOLL_CTL_MOD to re-arm once I’m done processing the events.
(My motivation is to use the same code path for handling a wakeup and creating a new socket: both of them could finish by calling
EPOLL_CTL_MOD to re-arm the event. However, I don’t want a spurious thread wakeup if an error occurs in the socket before the
According to the manpage, that is not possible. Both
EPOLLHUP claim that:
epoll_wait(2) will always wait for this event; it is not necessary to set it in events when calling epoll_ctl().
However, after reviewing eventpoll.c in the Linux source tree, it looks like if no "public"
events bits are set, the wakeup is suppressed. (Block comments in the original; line comments are my notes.)
/* Epoll private bits inside the event mask */ #define EP_PRIVATE_BITS (EPOLLWAKEUP | EPOLLONESHOT | EPOLLET | EPOLLEXCLUSIVE) // ...snip... // Inside the callback function that fires on epoll wakeup: /* * If the event mask does not contain any poll(2) event, we consider the * descriptor to be disabled. This condition is likely the effect of the * EPOLLONESHOT bit that disables the descriptor when an event is received, * until the next EPOLL_CTL_MOD will be issued. */ if (!(epi->event.events & ~EP_PRIVATE_BITS)) goto out_unlock; // Exits the callback without waking userspace
Two concrete questions:
Is my reading of the kernel source correct that
EPOLLHUP will not be triggered as long as no flags are specified apart from the four private bits?
Can I rely on this behavior that is undocumented in the man page?