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 EPOLLERR and 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 with 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 EPOLL_CTL_MOD).
According to the manpage, that is not possible. Both EPOLLERR and 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 EPOLLERR/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?