Integrate Timers into Linux Event Loops with timerfd
Event loops work best when unrelated kinds of work have one common waiting mechanism. Sockets become readable. Pipes become writable. A child-process descriptor or signal descriptor can become ready. Timers are often the awkward exception. A program can call sleep() or nanosleep(), but that blocks the thread instead of letting it wait for I/O. It can pass a timeout to poll() or epoll_wait(), but one timeout becomes difficult to manage when the program has several independent deadlines. Traditional POSIX timers can deliver signals, which introduces a second asynchronous control path.