The manpages of epoll do not mention the behavior in the presence of multiple threads. By trying it out, I found out that the following works: if one thread does epoll_wait() on an epoll in which some fd was not registered at all, and blocks; and later another thread does epoll_ctl() to add the fd; then the fd will be reported by the original thread's epoll_wait() as soon as it meets the condition. This behavior is something that may be very useful in some situations. As far as I see, it cannot be achieved easily with select(). I think that it should be officially mentioned in the manpages (provided it is not an accident but works this way by design).
Thanks for the report. You are right that it's useful and cannot be achieved with select(2) and poll(2).
I added the following to epoll_wait(2):
@@ -183,6 +183,16 @@ Library support is provided in glibc starting with version 2.6.
.SH CONFORMING TO
.BR epoll_wait ()
+While one thread is blocked in a call to
+.BR epoll_pwait (),
+it is possible for another thread to add a file descriptor to the waited-upon
+If the new file descriptor becomes ready,
+it will cause the
+.BR epoll_wait ()
+call to unblock.
.SH "SEE ALSO"
.BR epoll_create (2),
.BR epoll_ctl (2),