This is a library for watching file descriptors for events. It is designed to provide a simpler and lower-level API than libevent.


The module exposes a single new() function that creates a new state. It takes no arguments.

local poll = require"util.poll".new();

State methods

The state has three methods to manage which FDs to watch; :add(), :set() and :del().

All three take an FD number (integer) as first argument and except for :del() take booleans that signal interest in the FD becoming readable and/or writable, respectively.

All three return either a boolean true for success or a tripplet of nil, a textual error and an error code.

Then there is the :wait() method that waits until something happens to one of the registered FDs.

:add(fd, r, w)

Adds an FD to be watched. Arguments are the integer FD to watch and two optional booleans representing whether to watch for the FD becoming readable and/or writable.

local ok, err = poll:add(conn:getfd(), true, false);

:set(fd, r, w)

Changes which events to watch for. Arguments are the same as for :add().

local ok, err = poll:set(conn:getfd(), false, true);


Stops watching a FD. Takes no arguments beyond the integer FD.

local ok, err = poll:del(conn:getfd());


Waits (blocking) until one or more FDs have pending events, or the amount of time given in the timeout argument has passed.

When a pending event that is watched for happens, :wait() returns a triplet consisting of the integer FD number the event happened to and two booleans matching the arguments to :add() and :set(), i.e. whether the FD is readable and/or writable.

local fd, readable, writable = poll:wait(10);
if fd then
    if readable then print("Can read from FD " .. fd); end
    if writable then print("Can write to FD " .. fd); end
    local err = readable
    if err == "timeout" then
        print("10 seconds passed with no events");
    elseif err == "signal" then
        print("Interrupted by a signal");
        print("Some other error: "..err);

If the timeout is reached, it returns nil and the string "timeout".


This method only exists if util.poll is built on Linux with the epoll API. It returns the epoll FD, which can be watched like any other FD.