diff --git a/event.c b/event.c index 40be20b..8b00990 100644 --- a/event.c +++ b/event.c @@ -46,7 +46,7 @@ struct fd_entry { struct timeout_entry { struct list_head list; - struct timeval timeout; + struct timeval intervall; struct timeval nextrun; int (*callback)(void *privdata); void *privdata; @@ -77,46 +77,39 @@ int event_remove_fd(int fd) { struct fd_entry *entry, *tmp; list_for_each_entry_safe(entry, tmp, &fd_list, list) { - if (entry->fd == fd) { + if (entry->fd == fd) entry->flags |= FD_DELETE; - return 0; - } } - return -1; + return 0; } -static void calc_nextrun(struct timeval *timeout, struct timeval *nextrun) +static void add_timeval(struct timeval *ret, struct timeval *a, struct timeval *b) { - struct timeval now; - gettimeofday(&now, NULL); + ret->tv_usec = a->tv_usec + b->tv_usec; + ret->tv_sec = a->tv_sec + b->tv_sec; - nextrun->tv_usec = now.tv_usec + timeout->tv_usec; - nextrun->tv_sec = now.tv_sec + timeout->tv_sec; - - if (nextrun->tv_usec >= 1000000) { - nextrun->tv_usec -= 1000000; - nextrun->tv_sec++; + if (ret->tv_usec >= 1000000) { + ret->tv_usec -= 1000000; + ret->tv_sec++; } } -static void calc_timeout(struct timeval *timeout, struct timeval *nextrun) +static void sub_timeval(struct timeval *ret, struct timeval *a, struct timeval *b) { - struct timeval now; - gettimeofday(&now, NULL); + ret->tv_usec = a->tv_usec - b->tv_usec; + ret->tv_sec = a->tv_sec - b->tv_sec; - timeout->tv_usec = nextrun->tv_usec - now.tv_usec; - timeout->tv_sec = nextrun->tv_sec - now.tv_sec; - - if (timeout->tv_usec < 0) { - timeout->tv_usec += 1000000; - timeout->tv_sec--; + if (ret->tv_usec < 0) { + ret->tv_usec += 1000000; + ret->tv_sec--; } } -static void schedule_nextrun(struct timeout_entry *entry) +static void schedule_nextrun(struct timeout_entry *entry, struct timeval *now) { + add_timeval(&entry->nextrun, now, &entry->intervall); + struct timeout_entry *search; - list_for_each_entry(search, &timeout_list, list) { if (search->nextrun.tv_sec > entry->nextrun.tv_sec) { list_add_tail(&entry->list, &search->list); @@ -140,15 +133,21 @@ int event_add_timeout(struct timeval *timeout, int (*callback)(void *privdata), return -1; } - memcpy(&entry->timeout, timeout, sizeof(entry->timeout)); + memcpy(&entry->intervall, timeout, sizeof(entry->intervall)); entry->callback = callback; entry->privdata = privdata; - calc_nextrun(&entry->timeout, &entry->nextrun); - schedule_nextrun(entry); + struct timeval now; + gettimeofday(&now, NULL); + schedule_nextrun(entry, &now); return 0; } +int event_remove_timeout(int id) +{ + +} + int event_loop(void) { fd_set *fdsets = malloc(sizeof(fd_set) * 3); @@ -192,30 +191,37 @@ int event_loop(void) struct timeval timeout, *timeout_p = NULL; if (!list_empty(&timeout_list)) { + struct timeval now; + gettimeofday(&now, NULL); + struct timeout_entry *entry, *tmp; list_for_each_entry_safe(entry, tmp, &timeout_list, list) { + /* timeout elapsed */ + if (entry->nextrun.tv_sec < now.tv_sec || + (entry->nextrun.tv_sec == now.tv_sec && entry->nextrun.tv_usec < now.tv_usec)) { - calc_timeout(&timeout, &entry->nextrun); - if (timeout.tv_sec >= 0 && timeout.tv_usec > 0) { - timeout_p = &timeout; - break; - } + list_del(&entry->list); + if (entry->callback(entry->privdata)) { + free(entry); - // delayed timeout, exec NOW! - list_del(&entry->list); - int ret = entry->callback(entry->privdata); - if (ret == 0) { - calc_nextrun(&entry->timeout, &entry->nextrun); - schedule_nextrun(entry); + } else { + schedule_nextrun(entry, &now); + } } else { - free(entry); + break; } } + + entry = list_entry(timeout_list.next, typeof(*entry), list); + + /* calc select() timeout */ + sub_timeval(&timeout, &entry->nextrun, &now); + timeout_p = &timeout; } int i = select(FD_SETSIZE, readfds, writefds, exceptfds, timeout_p); - if (i < 0) { + if (i <= 0) { /* On error, -1 is returned, and errno is set * appropriately; the sets and timeout become * undefined, so do not rely on their contents @@ -223,23 +229,10 @@ int event_loop(void) */ continue; - } else if (i == 0 && !list_empty(&timeout_list)) { - struct timeout_entry *entry; - entry = list_entry(timeout_list.next, typeof(*entry), list); - list_del(&entry->list); - - int ret = entry->callback(entry->privdata); - if (ret == 0) { - calc_nextrun(&entry->timeout, &entry->nextrun); - schedule_nextrun(entry); - - } else { - free(entry); - } - } else { list_for_each_entry(entry, &fd_list, list) { if ((entry->flags & FD_NEW) != 0) { + /* entry has just been added, execute it next round */ continue; } else if ((entry->flags & FD_READ) != 0) { diff --git a/telnetproxy.c b/telnetproxy.c index 46a6e1d..b61cf53 100644 --- a/telnetproxy.c +++ b/telnetproxy.c @@ -2,6 +2,9 @@ #include #include +#include +#include + #include "configfile.h" #include "connection.h" #include "event.h" @@ -26,8 +29,15 @@ static int listen_init(const char *value, void *privdata) return 0; } +static int trigger(void *privdata) +{ + log_print(LOG_DEBUG, "%s", (char *)privdata); + return 0; +} + int main(int argc, char *argv[]) { +/* if (config_parse("telnetproxy.conf") == -1) return -1; @@ -42,6 +52,16 @@ int main(int argc, char *argv[]) log_print(LOG_ERROR, "no admin_listen sockets defined!"); return -1; } +*/ + struct timeval tv; + tv.tv_usec = 0; + + tv.tv_sec = 1; + event_add_timeout(&tv, trigger, "trigger 1"); + tv.tv_sec = 2; + event_add_timeout(&tv, trigger, "trigger 2"); + tv.tv_sec = 3; + event_add_timeout(&tv, trigger, "trigger 3"); event_loop();