Skip to content

epoll

Purpose

epoll provides scalable I/O event notification for applications that monitor many file descriptors.

Unlike poll(), an epoll instance keeps track of registered file descriptors and returns only those that are ready.

Common APIs

#include <sys/epoll.h>

int epoll_create1(int flags);

int epoll_ctl(int epfd,
              int op,
              int fd,
              struct epoll_event *event);

int epoll_wait(int epfd,
               struct epoll_event *events,
               int maxevents,
               int timeout);

epoll_ctl()

Registers, modifies, or removes a monitored file descriptor.

Common operations:

Operation Description
EPOLL_CTL_ADD Add a file descriptor
EPOLL_CTL_MOD Modify monitored events
EPOLL_CTL_DEL Remove a file descriptor

Example:

struct epoll_event ev = {
    .events = EPOLLIN,
    .data.fd = fd,
};

epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);

epoll_wait()

Waits until one or more monitored file descriptors become ready.

struct epoll_event events[16];

int n = epoll_wait(epfd,
                   events,
                   ARRAY_SIZE(events),
                   -1);

Timeout

Value Behavior
-1 Wait forever
0 Return immediately
>0 Wait up to the specified timeout (milliseconds)

Trigger Modes

Level Trigger (LT)

Default mode.

The event is reported as long as the file descriptor remains ready.

Edge Trigger (ET)

Enabled with:

EPOLLET

The event is reported only when readiness changes from not-ready to ready.

Applications typically continue reading until EAGAIN.

Driver Relationship

Device drivers do not implement epoll-specific callbacks.

The kernel calls the driver's standard .poll() callback to determine readiness.

Typical driver implementation:

static __poll_t mydev_poll(struct file *file,
                           poll_table *wait)
{
    poll_wait(file, &dev->wq, wait);

    if (data_available(dev))
        return POLLIN;

    return 0;
}

The same callback is shared by:

  • poll()
  • select()
  • epoll()

Common Pitfalls

Warning

Do not assume that EPOLLET repeatedly reports unread data. Edge Trigger reports only readiness transitions.

Warning

Device drivers should never implement epoll-specific logic. The standard .poll() callback is sufficient.

Warning

Applications using Edge Trigger should continue reading until no more data is available, typically indicated by EAGAIN.