How does a socket event get propagated/converted to epoll?
c, centos6, glibc, linux, linux-kernel
Solution
The most glaring problem with `epoll` documentation is its failure to state in "bold caps" that `epoll` events, are, in fact, fully identical to `poll` (2) events. Indeed, on the kernel side `epoll` handles its events in terms of older `poll` event names:
#define POLLIN 0x0001 // EPOLLIN
#define POLLPRI 0x0002 // EPOLLPRI
#define POLLOUT 0x0004 // EPOLLOUT
#define POLLERR 0x0008 // EPOLLERR
#define POLLHUP 0x0010 // EPOLLHUP
#define POLLNVAL 0x0020 // unused in epoll
#define POLLRDNORM 0x0040 // EPOLLRDNORM
#define POLLRDBAND 0x0080 // EPOLLRDBAND
#define POLLWRNORM 0x0100 // EPOLLWRNORM
#define POLLWRBAND 0x0200 // EPOLLWRBAND
#define POLLMSG 0x0400 // EPOLLMSG
#define POLLREMOVE 0x1000 // unused in epoll
#define POLLRDHUP 0x2000 // EPOLLRDHUP
Then, a brief inspection of kernel source reveals that:
`EPOLLIN` and `EPOLLRDNORM` are identical (epoll returns `EPOLLIN | EPOLLRDNORM` when data is available for reading from the file descriptor).
`EPOLLOUT` and `EPOLLWRNORM` are identical (epoll returns `EPOLLOUT | EPOLLWRNORM` when buffer space is available for writing).
`EPOLLRDBAND` and `EPOLLWRBAND` signal availability of the out of band data on the descriptor (on some sockets this will be the data send with `MSG_OOB` flag passed to socket).
`EPOLLPRI` is a modifier flag and always augments some other event (such as `EPOLLERR`). It's use is subsystem dependent, as it may mean somewhat different things depending on what purpose associated file descriptor serves.
`EPOLLMSG` appears to be unused by the kernel and appears to serve no purpose.
`EPOLLRDHUP` signals that the peer had closed its side of the channel for reading, but may still receive data (handy to establish that no more request data is coming in).
`EPOLLHUP` signals that the peer had closed its side of the channel.
Problem
I am curious how epoll_wait() receives the event that a registered socket (with epoll_ctl()) is ready for read/write. I believe that glibc magically handles it. Then, is there a document describing how the following events can be triggered for a socket? - EPOLLPRI - EPOLLRDNORM - EPOLLRDBAND - EPOLLWRNORM - EPOLLWRBAND - EPOLLMSG - EPOLLERR - EPOLLHUP - EPOLLRDHUP P.S. Originally I was trying to paste the enum EPOLL_EVENTS in sys/epoll.h on my box here; stackoverflow thinks that I don't format the code block correctly although I wrapped it with pre and then code tag, any idea?