epoll_wait(2)
๐ epoll_wait(2) โ bestie edition ๐
okay so this is the manual page for epoll_wait, epoll_pwait, and epoll_pwait2 โ three little legends from the Linux man-pages fam, living in section 2 (the System Calls Manual, iykyk). they wait for I/O events on an epoll file descriptor and honestly? iconic behavior. no cap. ๐ฆ
โจ NAME โจ
epoll_wait, epoll_pwait, epoll_pwait2 โ wait for an I/O event on an epoll file descriptor ๐
๐ LIBRARY ๐
Standard C library (libc, -lc)
๐ SYNOPSIS ๐
#include <sys/epoll.h>
int epoll_wait(int n;
int epfd, struct epoll_event events[n], int n,
int timeout);
int epoll_pwait(int n;
int epfd, struct epoll_event events[n], int n,
int timeout,
const sigset_t *_Nullable sigmask);
int epoll_pwait2(int n;
int epfd, struct epoll_event events[n], int n,
const struct timespec *_Nullable timeout,
const sigset_t *_Nullable sigmask);
๐ธ DESCRIPTION ๐ธ
okay so the epoll_wait() system call literally just sits there and waits for events on the epoll(7) instance that the file descriptor epfd is pointing at. the buffer that events points to is where all the tea gets returned โ info from the ready list about the file descriptors in the interest list that have some events available. up to n of them come back from epoll_wait(), and the n argument must be greater than zero, periodt.
the timeout argument is how many milliseconds epoll_wait() is gonna block for. time is measured against the CLOCK_MONOTONIC clock (โจ the clock of truth โจ).
so a call to epoll_wait() will block until one of these three things happens:
- a file descriptor delivers an event ๐
- the call gets interrupted by a signal handler ๐ญ
- the timeout expires โฐ
heads up bestie: the timeout interval gets rounded up to the system clock granularity, and kernel scheduling delays mean the blocking interval might overrun by a little bit. nature of the game. and:
- timeout of
-1โepoll_wait()blocks forever, like it's waiting for him to text back ๐ - timeout of
0โepoll_wait()returns immediately, even if there are zero events available. she's not waiting around.
the struct epoll_event is described over in epoll_event(3type).
the data field of each returned epoll_event structure holds the exact same data that was specified in the most recent call to epoll_ctl(2) (EPOLL_CTL_ADD, EPOLL_CTL_MOD) for the corresponding open file descriptor. same data, no changes, we keep the receipts bestie ๐งพ
the events field is a bit mask that shows which events have occurred for the corresponding open file description. want the full list of bits that can show up in this mask? go look at epoll_ctl(2). ๐
๐ซ epoll_pwait() ๐ซ
the relationship between epoll_wait() and epoll_pwait() is exactly like the relationship between select(2) and pselect(2) โ it's giving siblings. just like pselect(2), epoll_pwait() lets an application safely wait until either a file descriptor becomes ready or a signal is caught. ๐ซถ
this following epoll_pwait() call:
ready = epoll_pwait(epfd, &events, n, timeout, &sigmask);
is equivalent to atomically executing these calls:
sigset_t origmask;
pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
ready = epoll_wait(epfd, &events, n, timeout);
pthread_sigmask(SIG_SETMASK, &origmask, NULL);
the sigmask argument can be specified as NULL, and in that case epoll_pwait() is just equivalent to epoll_wait(). twins fr fr. ๐ฏ
๐ epoll_pwait2() ๐
the epoll_pwait2() system call is equivalent to epoll_pwait() except for the timeout argument. it takes an argument of type timespec so you can specify a nanosecond resolution timeout. she's precise like that. โฑ๏ธ this argument functions the same as in pselect(2) and ppoll(2). if timeout is NULL, then epoll_pwait2() can block indefinitely โ main character energy, no time limit. ๐
๐ RETURN VALUE ๐
on success, epoll_wait() returns the number of file descriptors ready for the requested I/O operation. or zero, if no file descriptor became ready during the requested timeout milliseconds (sad, but valid). on failure, epoll_wait() returns -1 and errno is set to indicate the error. ๐ค
๐ ERRORS ๐
EBADFโ theepfdis not a valid file descriptor. it's giving fake.EFAULTโ the memory area pointed to byeventsis not accessible with write permissions. rude.EINTRโ the call was interrupted by a signal handler before either (1) any of the requested events occurred or (2) the timeout expired; seesignal(7).EINVALโ theepfdis not an epoll file descriptor, ornis less than or equal to zero. (yes,n <= 0is a crime here, bestie.)
โญ STANDARDS โญ
Linux. that's it, that's the standard. ๐ง
๐ HISTORY ๐
epoll_wait()โ Linux 2.6, glibc 2.3.2. a true vintage.epoll_pwait()โ Linux 2.6.19, glibc 2.6. glow up era.epoll_pwait2()โ Linux 5.11. the new kid, and she's slaying.
๐ฆ NOTES ๐ฆ
while one thread is blocked in a call to epoll_wait(), it's totally possible for another thread to add a file descriptor to the waited-upon epoll instance. and if that new file descriptor becomes ready, it will cause the epoll_wait() call to unblock. teamwork makes the dream work ๐ซถ
if more than n file descriptors are ready when epoll_wait() is called, then successive epoll_wait() calls will round robin through the set of ready file descriptors. this behavior helps avoid starvation scenarios, where a process fails to notice that additional file descriptors are ready because it's focusing on a set of file descriptors that are already known to be ready. like, girl, look around. ๐
also note that it's possible to call epoll_wait() on an epoll instance whose interest list is currently empty โ or whose interest list becomes empty because file descriptors are closed or removed from the interest in another thread. the call will block until some file descriptor is later added to the interest list (in another thread) and that file descriptor becomes ready. manifesting events. ๐
๐ C library/kernel differences ๐
the raw epoll_pwait() and epoll_pwait2() system calls have a sixth argument, size_t sigsetsize, which specifies the size in bytes of the sigmask argument. the glibc epoll_pwait() wrapper function specifies this argument as a fixed value (equal to sizeof(sigset_t)). glibc said "I got it, don't worry about it." ๐
๐ BUGS ๐
before Linux 2.6.37, a timeout value larger than approximately LONG_MAX / HZ milliseconds is treated as -1 (i.e., infinity). so for example, on a system where sizeof(long) is 4 and the kernel HZ value is 1000, this means that timeouts greater than 35.79 minutes are treated as infinity. not her rounding up, just straight up ignoring you. old kernel behavior, we don't miss it. ๐
๐ฅ SEE ALSO ๐ฅ
epoll_create(2), epoll_ctl(2), epoll(7)
and that's the whole page bestie, you ate that. ๐ฝ๏ธโจ
this lil tour came to you from Linux man-pages 6.20, dated 2026-02-08 โ drop a ๐ for epoll_wait(2) and go make your event loop iconic. ๐๐๐ฆ
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- ๐ the page's license: GPL-2.0-or-later
- Copyright 2003, Davide Libenzi <davidel@xmailserver.org>
- Copyright 2007-2018, Michael Kerrisk <tk.manpages@gmail.com>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms