sig_loop.h

include/sig/runtime/sig_loop.h

The event loop of a single-threaded host: file-descriptor watches, one-shot timers and a per-iteration "step" hook (the runtime's service step), all dispatched from one thread. It is built on sig_poller, so the same code runs over poll(), kqueue or epoll. Everything except sig_loop_wake() and sig_loop_stop() must be called on the thread that runs sig_loop_run() (or before it starts). Callbacks run on that thread and may freely add, change and remove watches and timers, including their own.

sig_loop

typedef struct sig_loop sig_loop;

sig_loop_watch

typedef struct sig_loop_watch sig_loop_watch;

sig_loop_timer

typedef struct sig_loop_timer sig_loop_timer;

sig_loop_create

sig_status_t sig_loop_create(sig_loop ** out)
ParameterType
outsig_loop **

sig_loop_destroy

void sig_loop_destroy(sig_loop * loop)
ParameterType
loopsig_loop *

Frees the loop and any watches and timers still registered (their fds are not closed). Not while sig_loop_run() is running. NULL is a no-op.

sig_loop_fd_fn

typedef void (*sig_loop_fd_fn)(int fd, unsigned events, void *ctx);

Called when fd is ready; `events` is a SIG_POLL_* mask.

sig_loop_watch_fd

sig_status_t sig_loop_watch_fd(sig_loop * loop, int fd, unsigned events, sig_loop_fd_fn cb, void * ctx, sig_loop_watch ** out)
ParameterType
loopsig_loop *
fdint
eventsunsigned
cbsig_loop_fd_fn
ctxvoid *
outsig_loop_watch **

Watches fd for `events` (SIG_POLL_READ / SIG_POLL_WRITE; errors are always reported). *out is the handle for modify/unwatch. The caller keeps ownership of the fd and must sig_loop_unwatch() before closing it. SIG_ERR_EXISTS if fd is already watched.

sig_loop_watch_modify

sig_status_t sig_loop_watch_modify(sig_loop_watch * watch, unsigned events)
ParameterType
watchsig_loop_watch *
eventsunsigned

shared with sig_loop_watch_fd

Watches fd for `events` (SIG_POLL_READ / SIG_POLL_WRITE; errors are always reported). *out is the handle for modify/unwatch. The caller keeps ownership of the fd and must sig_loop_unwatch() before closing it. SIG_ERR_EXISTS if fd is already watched.

sig_loop_unwatch

void sig_loop_unwatch(sig_loop_watch * watch)
ParameterType
watchsig_loop_watch *

shared with sig_loop_watch_fd

Watches fd for `events` (SIG_POLL_READ / SIG_POLL_WRITE; errors are always reported). *out is the handle for modify/unwatch. The caller keeps ownership of the fd and must sig_loop_unwatch() before closing it. SIG_ERR_EXISTS if fd is already watched.

sig_loop_timer_fn

typedef void (*sig_loop_timer_fn)(void *ctx);

One-shot timer: cb runs once, no earlier than `deadline` (absolute CLOCK_MONOTONIC, as from sig_time_now()). The handle is valid until the callback is entered or sig_loop_timer_cancel() is called; a holder must forget it in the callback.

sig_loop_timer_start

sig_status_t sig_loop_timer_start(sig_loop * loop, const struct timespec * deadline, sig_loop_timer_fn cb, void * ctx, sig_loop_timer ** out)
ParameterType
loopsig_loop *
deadlineconst struct timespec *
cbsig_loop_timer_fn
ctxvoid *
outsig_loop_timer **

shared with sig_loop_timer_fn

One-shot timer: cb runs once, no earlier than `deadline` (absolute CLOCK_MONOTONIC, as from sig_time_now()). The handle is valid until the callback is entered or sig_loop_timer_cancel() is called; a holder must forget it in the callback.

sig_loop_timer_cancel

void sig_loop_timer_cancel(sig_loop_timer * timer)
ParameterType
timersig_loop_timer *

shared with sig_loop_timer_fn

One-shot timer: cb runs once, no earlier than `deadline` (absolute CLOCK_MONOTONIC, as from sig_time_now()). The handle is valid until the callback is entered or sig_loop_timer_cancel() is called; a holder must forget it in the callback.

sig_loop_step_fn

typedef void (*sig_loop_step_fn)(void *ctx, bool *out_has_deadline, struct timespec *out_deadline);

The step hook runs at the top of every iteration and reports when it next needs to run (*out_has_deadline false: only when woken). The host points it at sig_runtime_step().

sig_loop_set_step

void sig_loop_set_step(sig_loop * loop, sig_loop_step_fn fn, void * ctx)
ParameterType
loopsig_loop *
fnsig_loop_step_fn
ctxvoid *

shared with sig_loop_step_fn

The step hook runs at the top of every iteration and reports when it next needs to run (*out_has_deadline false: only when woken). The host points it at sig_runtime_step().

sig_loop_run

sig_status_t sig_loop_run(sig_loop * loop)
ParameterType
loopsig_loop *

Runs until sig_loop_stop(): step, fire due timers, sleep until the earliest of the step deadline and the next timer or fd event, dispatch, repeat. A stop requested before the loop starts makes it return at once.

sig_loop_wake

void sig_loop_wake(sig_loop * loop)
ParameterType
loopsig_loop *

Any thread. Makes the loop run its step hook now.

sig_loop_stop

void sig_loop_stop(sig_loop * loop)
ParameterType
loopsig_loop *

Any thread. Makes sig_loop_run() return after the current iteration.