epoll¶
epoll is Linux's scalable file descriptor event notification mechanism. It is commonly used for servers, device event loops, and applications that need to monitor many file descriptors.
What Problem It Solves¶
Compared with select() and poll(), epoll is designed for larger fd sets and event-driven applications.
Key APIs¶
| API | Purpose |
|---|---|
epoll_create1() |
Create an epoll instance |
epoll_ctl() |
Add, modify, or remove monitored fds |
epoll_wait() |
Wait for ready events |
Typical Workflow¶
epoll_create1()
↓
epoll_ctl(ADD listen_fd)
↓
epoll_ctl(ADD timer_fd)
↓
epoll_ctl(ADD signal_fd)
↓
epoll_wait()
↓
dispatch event
Minimal Pattern¶
int epfd = epoll_create1(EPOLL_CLOEXEC);
struct epoll_event ev;
/* Register fd. */
ev.events = EPOLLIN;
ev.data.fd = fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
while (1) {
struct epoll_event events[16];
int n = epoll_wait(epfd, events, 16, -1);
if (n < 0) {
if (errno == EINTR)
continue;
break;
}
for (int i = 0; i < n; i++) {
if (events[i].events & EPOLLIN) {
/* Read and handle the event. */
}
}
}
Context-Based Dispatch¶
For larger programs, it is usually cleaner to store a pointer in event.data.ptr instead of using only event.data.fd.
This allows one event loop to handle:
- server socket
- client socket
- timerfd
- signalfd
- eventfd
- device fd
Level-Triggered Behavior¶
The default epoll mode is level-triggered.
If an fd remains readable, epoll_wait() may keep reporting it as ready. The application should read until the event is consumed or until non-blocking read() returns EAGAIN.
Common Pitfalls¶
| Pitfall | Result |
|---|---|
| Not using non-blocking sockets | Event loop may block inside read() or send() |
| Forgetting to remove closed fds | Stale fd references or confusing behavior |
Not handling EPOLLHUP / EPOLLERR |
Broken connections are not cleaned up correctly |
| Not draining readable fd | Repeated wakeups |
| Mixing fd ownership incorrectly | Double close or use-after-close bugs |
Related Labs¶
- Day48 - Epoll + Timerfd
- Day49 - signalfd + epoll
- Day50 - Pollable Character Driver
- Day51 - Timer-based Pollable Driver