/*
- event.c -- I/O, timeout and signal event handling
+ event.c -- I/O and timeout event handling
Copyright (C) 2014 Guus Sliepen <guus@meshlink.io>
This program is free software; you can redistribute it and/or modify
timeout->tv = (struct timeval){0, 0};
}
-static int signal_compare(const signal_t *a, const signal_t *b) {
- return (int)a->signum - (int)b->signum;
-}
-
-static void signalio_handler(event_loop_t *loop, void *data, int flags) {
- unsigned char signum;
- if(read(loop->pipefd[0], &signum, 1) != 1)
- return;
-
- signal_t *sig = splay_search(&loop->signals, &((signal_t){.signum = signum}));
- if(sig)
- sig->cb(loop, sig->data);
-}
-
-static void pipe_init(event_loop_t *loop) {
- if(!pipe(loop->pipefd))
- io_add(loop, &loop->signalio, signalio_handler, NULL, loop->pipefd[0], IO_READ);
-}
-
-void signal_add(event_loop_t *loop, signal_t *sig, signal_cb_t cb, void *data, uint8_t signum) {
- if(sig->cb)
- return;
-
- sig->cb = cb;
- sig->data = data;
- sig->signum = signum;
- sig->node.data = sig;
-
- if(loop->pipefd[0] == -1)
- pipe_init(loop);
-
- if(!splay_insert_node(&loop->signals, &sig->node))
- abort();
-}
-
-void signal_del(event_loop_t *loop, signal_t *sig) {
- if(!sig->cb)
- return;
-
- splay_unlink_node(&loop->signals, &sig->node);
- sig->cb = NULL;
-}
-
bool event_loop_run(event_loop_t *loop) {
loop->running = true;
void event_loop_init(event_loop_t *loop) {
loop->ios.compare = (splay_compare_t)io_compare;
loop->timeouts.compare = (splay_compare_t)timeout_compare;
- loop->signals.compare = (splay_compare_t)signal_compare;
- loop->pipefd[0] = -1;
- loop->pipefd[1] = -1;
gettimeofday(&loop->now, NULL);
}
splay_free_node(&loop->ios, node);
for splay_each(timeout_t, timeout, &loop->timeouts)
splay_free_node(&loop->timeouts, node);
- for splay_each(signal_t, signal, &loop->signals)
- splay_free_node(&loop->signals, node);
}
/*
- event.h -- I/O, timeout and signal event handling
+ event.h -- I/O and timeout event handling
Copyright (C) 2014 Guus Sliepen <guus@meshlink.io>
This program is free software; you can redistribute it and/or modify
typedef void (*io_cb_t)(event_loop_t *loop, void *data, int flags);
typedef void (*timeout_cb_t)(event_loop_t *loop, void *data);
-typedef void (*signal_cb_t)(event_loop_t *loop, void *data);
typedef struct io_t {
int fd;
struct splay_node_t node;
} timeout_t;
-typedef struct signal_t {
- int signum;
- signal_cb_t cb;
- void *data;
- struct splay_node_t node;
-} signal_t;
-
struct event_loop_t {
fd_set readfds;
fd_set writefds;
splay_tree_t ios;
splay_tree_t timeouts;
- splay_tree_t signals;
-
- io_t signalio;
- int pipefd[2];
void *data;
};
extern void timeout_del(event_loop_t *loop, timeout_t *timeout);
extern void timeout_set(event_loop_t *loop, timeout_t *timeout, struct timeval *tv);
-extern void signal_add(event_loop_t *loop, signal_t *sig, signal_cb_t cb, void *data, uint8_t signum);
-extern void signal_trigger(event_loop_t *loop, signal_t *sig);
-extern void signal_del(event_loop_t *loop, signal_t *sig);
-
extern void event_loop_init(event_loop_t *loop);
extern void event_loop_exit(event_loop_t *loop);
extern bool event_loop_run(event_loop_t *loop);