sig_poller.h

include/sig/platform/sig_poller.h

The readiness-notification backend under sig_loop (see sig_loop.h): the one place that knows about poll(), kqueue or epoll. Exactly one implementation is linked into libsig, chosen with -DSIG_POLLER=<name> (src/platform/posix/sig_poller_<name>.c). A port to another system supplies its own file with these functions; the loop and everything above it are unchanged. A poller watches file descriptors (sockets, pipes) for readiness. Rules every backend must keep: - Level-triggered: an fd stays reported for as long as it is ready. Callers read or write once per report and rely on being told again. - Only sig_poller_wake() may be called from a thread other than the one in sig_poller_wait(). Add, modify and remove are made by the waiting thread (or before it starts). - An fd that is closed must be removed first.

SIG_POLL_READ

#define SIG_POLL_READ  0x1u

readable, or a connection to accept, or the peer closed

SIG_POLL_WRITE

#define SIG_POLL_WRITE 0x2u

writable

SIG_POLL_ERROR

#define SIG_POLL_ERROR 0x4u

error or hang-up; set alongside the events asked for, never requested

sig_poller

typedef struct sig_poller sig_poller;

sig_poller_event

typedef struct {
    int fd;
    unsigned events; /* SIG_POLL_* bits */
} sig_poller_event;

sig_poller_create

sig_status_t sig_poller_create(sig_poller ** out)
ParameterType
outsig_poller **

sig_poller_destroy

void sig_poller_destroy(sig_poller * p)
ParameterType
psig_poller *

sig_poller_add

sig_status_t sig_poller_add(sig_poller * p, int fd, unsigned events)
ParameterType
psig_poller *
fdint
eventsunsigned

Starts watching fd for `events` (SIG_POLL_READ and/or SIG_POLL_WRITE; 0 is allowed and parks the fd -- some systems then report nothing for it, not even errors). SIG_ERR_EXISTS if fd is already watched.

sig_poller_modify

sig_status_t sig_poller_modify(sig_poller * p, int fd, unsigned events)
ParameterType
psig_poller *
fdint
eventsunsigned

Changes the interest of a watched fd. SIG_ERR_NOT_FOUND if it is not.

sig_poller_remove

void sig_poller_remove(sig_poller * p, int fd)
ParameterType
psig_poller *
fdint

Stops watching fd. Not watched is a no-op.

sig_poller_wait

sig_status_t sig_poller_wait(sig_poller * p, int timeout_ms, sig_poller_event * out, size_t max, size_t * out_n)
ParameterType
psig_poller *
timeout_msint
outsig_poller_event *
maxsize_t
out_nsize_t *

Waits up to timeout_ms (negative: no limit, 0: just poll) for readiness and stores up to `max` events in `out`; *out_n is how many. SIG_OK with *out_n == 0 is a timeout, a sig_poller_wake(), or an interrupted wait. Anything ready beyond `max` is reported by the next call.

sig_poller_wake

void sig_poller_wake(sig_poller * p)
ParameterType
psig_poller *

Makes a current or the next sig_poller_wait() return early. Safe from any thread; wakes coalesce.