X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fevent.c;h=5a1e4f5b7dbf49ba45ea8a2aba63985c44cc3afd;hb=41583d5dcfc1277b1a203478de4cce2cd0cda1b1;hp=fdbf11d151bcb2e73d484d2ca790f749790cd6c6;hpb=d9c70767aa6da8b62b4a1034d5f07892603beddd;p=tinc diff --git a/src/event.c b/src/event.c index fdbf11d1..5a1e4f5b 100644 --- a/src/event.c +++ b/src/event.c @@ -1,6 +1,6 @@ /* event.c -- I/O, timeout and signal event handling - Copyright (C) 2012 Guus Sliepen + Copyright (C) 2012-2013 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,6 +19,7 @@ #include "system.h" +#include "dropin.h" #include "event.h" #include "net.h" #include "utils.h" @@ -36,16 +37,23 @@ static int io_compare(const io_t *a, const io_t *b) { static int timeout_compare(const timeout_t *a, const timeout_t *b) { struct timeval diff; timersub(&a->tv, &b->tv, &diff); - return diff.tv_sec ?: diff.tv_usec ?: a < b ? -1 : a > b ? 1 : 0; -} - -static int signal_compare(const signal_t *a, const signal_t *b) { - return a->signum - b->signum; + if(diff.tv_sec < 0) + return -1; + if(diff.tv_sec > 0) + return 1; + if(diff.tv_usec < 0) + return -1; + if(diff.tv_usec > 0) + return 1; + if(a < b) + return -1; + if(a > b) + return 1; + return 0; } static splay_tree_t io_tree = {.compare = (splay_compare_t)io_compare}; static splay_tree_t timeout_tree = {.compare = (splay_compare_t)timeout_compare}; -static splay_tree_t signal_tree = {.compare = (splay_compare_t)signal_compare}; void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) { if(io->cb) @@ -58,7 +66,8 @@ void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) { io_set(io, flags); - splay_insert_node(&io_tree, &io->node); + if(!splay_insert_node(&io_tree, &io->node)) + abort(); } void io_set(io_t *io, int flags) { @@ -86,9 +95,6 @@ void io_del(io_t *io) { } void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval *tv) { - if(timeout->cb) - return; - timeout->cb = cb; timeout->data = data; timeout->node.data = timeout; @@ -97,7 +103,7 @@ void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval } void timeout_set(timeout_t *timeout, struct timeval *tv) { - if(timeout->tv.tv_sec) + if(timerisset(&timeout->tv)) splay_unlink_node(&timeout_tree, &timeout->node); if(!now.tv_sec) @@ -105,7 +111,8 @@ void timeout_set(timeout_t *timeout, struct timeval *tv) { timeradd(&now, tv, &timeout->tv); - splay_insert_node(&timeout_tree, &timeout->node); + if(!splay_insert_node(&timeout_tree, &timeout->node)) + abort(); } void timeout_del(timeout_t *timeout) { @@ -113,12 +120,18 @@ void timeout_del(timeout_t *timeout) { return; splay_unlink_node(&timeout_tree, &timeout->node); - timeout->cb = NULL; + timeout->cb = 0; + timeout->tv = (struct timeval){0, 0}; } #ifndef HAVE_MINGW +static int signal_compare(const signal_t *a, const signal_t *b) { + return a->signum - b->signum; +} + static io_t signalio; static int pipefd[2] = {-1, -1}; +static splay_tree_t signal_tree = {.compare = (splay_compare_t)signal_compare}; static void signal_handler(int signum) { unsigned char num = signum; @@ -154,7 +167,8 @@ void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum) { signal(sig->signum, signal_handler); - splay_insert_node(&signal_tree, &sig->node); + if(!splay_insert_node(&signal_tree, &sig->node)) + abort(); } void signal_del(signal_t *sig) { @@ -231,6 +245,12 @@ bool event_loop(void) { return true; } +void event_flush_output(void) { + for splay_each(io_t, io, &io_tree) + if(FD_ISSET(io->fd, &writefds)) + io->cb(io->data, IO_WRITE); +} + void event_exit(void) { running = false; }