From f83bd22fe2dcb3ca0ddb9321944ee0b9c9b61ea6 Mon Sep 17 00:00:00 2001 From: pk910 Date: Sat, 17 Nov 2012 17:53:10 +0100 Subject: [PATCH] [IOMultiplexer] added auto-reloading timers --- src/IOEngine_epoll.c | 20 ++++++++++++++++---- src/IOEngine_kevent.c | 20 ++++++++++++++++---- src/IOEngine_select.c | 20 ++++++++++++++++---- src/IOEngine_win32.c | 22 +++++++++++++++++----- src/IOHandler.c | 29 ++++++++++++++++++++++++++++- src/IOHandler.h | 2 ++ src/test/timer/iotest.c | 7 ++++--- 7 files changed, 99 insertions(+), 21 deletions(-) diff --git a/src/IOEngine_epoll.c b/src/IOEngine_epoll.c index e363949..d1c139f 100644 --- a/src/IOEngine_epoll.c +++ b/src/IOEngine_epoll.c @@ -83,8 +83,14 @@ static void engine_epoll_loop(struct timeval *timeout) { tdiff.tv_sec = timer_priority->timeout.tv_sec - now.tv_sec; tdiff.tv_usec = timer_priority->timeout.tv_usec - now.tv_usec; if(tdiff.tv_sec < 0 || (tdiff.tv_sec == 0 && tdiff.tv_usec <= 0)) { - iohandler_events(timer_priority, 0, 0); - iohandler_close(timer_priority); //also sets timer_priority to the next timed element + if(timer_priority->constant_timeout) { + tdiff.tv_sec = 0; + iohandler_set_timeout(timer_priority, &tdiff); + iohandler_events(timer_priority, 0, 0); + } else { + iohandler_events(timer_priority, 0, 0); + iohandler_close(timer_priority); //also sets timer_priority to the next timed element + } continue; } else if(tdiff.tv_usec < 0) { tdiff.tv_sec--; @@ -120,8 +126,14 @@ static void engine_epoll_loop(struct timeval *timeout) { tdiff.tv_sec = timer_priority->timeout.tv_sec - now.tv_sec; tdiff.tv_usec = timer_priority->timeout.tv_usec - now.tv_usec; if(tdiff.tv_sec < 0 || (tdiff.tv_sec == 0 && tdiff.tv_usec <= 0)) { - iohandler_events(timer_priority, 0, 0); - iohandler_close(timer_priority); //also sets timer_priority to the next timed element + if(timer_priority->constant_timeout) { + tdiff.tv_sec = 0; + iohandler_set_timeout(timer_priority, &tdiff); + iohandler_events(timer_priority, 0, 0); + } else { + iohandler_events(timer_priority, 0, 0); + iohandler_close(timer_priority); //also sets timer_priority to the next timed element + } continue; } break; diff --git a/src/IOEngine_kevent.c b/src/IOEngine_kevent.c index f729dbb..ee93f86 100644 --- a/src/IOEngine_kevent.c +++ b/src/IOEngine_kevent.c @@ -89,8 +89,14 @@ static void engine_kevent_loop(struct timeval *timeout) { tdiff.tv_sec = timer_priority->timeout.tv_sec - now.tv_sec; tdiff.tv_usec = timer_priority->timeout.tv_usec - now.tv_usec; if(tdiff.tv_sec < 0 || (tdiff.tv_sec == 0 && tdiff.tv_usec <= 0)) { - iohandler_events(timer_priority, 0, 0); - iohandler_close(timer_priority); //also sets timer_priority to the next timed element + if(timer_priority->constant_timeout) { + tdiff.tv_sec = 0; + iohandler_set_timeout(timer_priority, &tdiff); + iohandler_events(timer_priority, 0, 0); + } else { + iohandler_events(timer_priority, 0, 0); + iohandler_close(timer_priority); //also sets timer_priority to the next timed element + } continue; } else if(tdiff.tv_usec < 0) { tdiff.tv_sec--; @@ -130,8 +136,14 @@ static void engine_kevent_loop(struct timeval *timeout) { tdiff.tv_sec = timer_priority->timeout.tv_sec - now.tv_sec; tdiff.tv_usec = timer_priority->timeout.tv_usec - now.tv_usec; if(tdiff.tv_sec < 0 || (tdiff.tv_sec == 0 && tdiff.tv_usec <= 0)) { - iohandler_events(timer_priority, 0, 0); - iohandler_close(timer_priority); //also sets timer_priority to the next timed element + if(timer_priority->constant_timeout) { + tdiff.tv_sec = 0; + iohandler_set_timeout(timer_priority, &tdiff); + iohandler_events(timer_priority, 0, 0); + } else { + iohandler_events(timer_priority, 0, 0); + iohandler_close(timer_priority); //also sets timer_priority to the next timed element + } continue; } break; diff --git a/src/IOEngine_select.c b/src/IOEngine_select.c index 48d7fed..aff5fb9 100644 --- a/src/IOEngine_select.c +++ b/src/IOEngine_select.c @@ -120,8 +120,14 @@ static void engine_select_loop(struct timeval *timeout) { tdiff.tv_sec = timer_priority->timeout.tv_sec - now.tv_sec; tdiff.tv_usec = timer_priority->timeout.tv_usec - now.tv_usec; if(tdiff.tv_sec < 0 || (tdiff.tv_sec == 0 && tdiff.tv_usec <= 0)) { - iohandler_events(timer_priority, 0, 0); - iohandler_close(timer_priority); //also sets timer_priority to the next timed element + if(timer_priority->constant_timeout) { + tdiff.tv_sec = 0; + iohandler_set_timeout(timer_priority, &tdiff); + iohandler_events(timer_priority, 0, 0); + } else { + iohandler_events(timer_priority, 0, 0); + iohandler_close(timer_priority); //also sets timer_priority to the next timed element + } continue; } else if(tdiff.tv_usec < 0) { tdiff.tv_sec--; @@ -182,8 +188,14 @@ static void engine_select_loop(struct timeval *timeout) { engine_select_timer_delay_fix = ((engine_select_timer_delay_fix * 19) + timer_fix) / 20; iohandler_log(IOLOG_DEBUG, "timer delay fix set to: %d us", engine_select_timer_delay_fix); } - iohandler_events(timer_priority, 0, 0); - iohandler_close(timer_priority); //also sets timer_priority to the next timed element + if(timer_priority->constant_timeout) { + tdiff.tv_sec = 0; + iohandler_set_timeout(timer_priority, &tdiff); + iohandler_events(timer_priority, 0, 0); + } else { + iohandler_events(timer_priority, 0, 0); + iohandler_close(timer_priority); //also sets timer_priority to the next timed element + } continue; } break; diff --git a/src/IOEngine_win32.c b/src/IOEngine_win32.c index bce6fc1..e29f8e5 100644 --- a/src/IOEngine_win32.c +++ b/src/IOEngine_win32.c @@ -63,8 +63,14 @@ static LRESULT CALLBACK engine_win32_wndproc(HWND hWnd, UINT uMsg, WPARAM wParam tdiff.tv_sec = timer_priority->timeout.tv_sec - now.tv_sec; tdiff.tv_usec = timer_priority->timeout.tv_usec - now.tv_usec; if(tdiff.tv_sec < 0 || (tdiff.tv_sec == 0 && tdiff.tv_usec <= 0)) { - iohandler_events(timer_priority, 0, 0); - iohandler_close(timer_priority); //also sets timer_priority to the next timed element + if(timer_priority->constant_timeout) { + tdiff.tv_sec = 0; + iohandler_set_timeout(timer_priority, &tdiff); + iohandler_events(timer_priority, 0, 0); + } else { + iohandler_events(timer_priority, 0, 0); + iohandler_close(timer_priority); //also sets timer_priority to the next timed element + } continue; } break; @@ -213,9 +219,15 @@ static void engine_win32_loop(struct timeval *timeout) { while(timer_priority) { tdiff.tv_sec = timer_priority->timeout.tv_sec - now.tv_sec; tdiff.tv_usec = timer_priority->timeout.tv_usec - now.tv_usec; - if(tdiff.tv_sec < 0 || (tdiff.tv_sec == 0 && tdiff.tv_usec < 1000)) { - iohandler_events(timer_priority, 0, 0); - iohandler_close(timer_priority); //also sets timer_priority to the next timed element + if(tdiff.tv_sec < 0 || (tdiff.tv_sec == 0 && tdiff.tv_usec < 100)) { + if(timer_priority->constant_timeout) { + tdiff.tv_sec = 0; + iohandler_set_timeout(timer_priority, &tdiff); + iohandler_events(timer_priority, 0, 0); + } else { + iohandler_events(timer_priority, 0, 0); + iohandler_close(timer_priority); //also sets timer_priority to the next timed element + } continue; } else if(tdiff.tv_usec < 0) { tdiff.tv_sec--; diff --git a/src/IOHandler.c b/src/IOHandler.c index 07cd794..b2a391b 100644 --- a/src/IOHandler.c +++ b/src/IOHandler.c @@ -235,7 +235,14 @@ void iohandler_set_timeout(struct IODescriptor *descriptor, struct timeval *time descriptor->next->prev = descriptor->prev; if(descriptor == timer_priority) timer_priority = descriptor->next; - if(timeout) { + if(timeout && timeout->tv_sec == 0 && descriptor->constant_timeout) { + descriptor->timeout.tv_usec += (descriptor->constant_timeout % 1000) * 1000; + descriptor->timeout.tv_sec += (descriptor->constant_timeout / 1000); + if(descriptor->timeout.tv_usec > 1000000) { + descriptor->timeout.tv_sec += (descriptor->timeout.tv_usec / 1000000); + descriptor->timeout.tv_usec %= 1000000; + } + } else if(timeout) { descriptor->timeout = *timeout; if(descriptor->timeout.tv_usec > 1000000) { descriptor->timeout.tv_usec -= 1000000; @@ -268,6 +275,26 @@ struct IODescriptor *iohandler_timer(struct timeval timeout, iohandler_callback return descriptor; } +struct IODescriptor *iohandler_constant_timer(int msec, iohandler_callback *callback) { + struct IODescriptor *descriptor; + struct timeval timeout; + gettimeofday(&timeout, NULL); + timeout.tv_usec += (msec % 1000) * 1000; + timeout.tv_sec += (msec / 1000); + if(timeout.tv_usec > 1000000) { + timeout.tv_sec += (timeout.tv_usec / 1000000); + timeout.tv_usec %= 1000000; + } + descriptor = iohandler_add(-1, IOTYPE_TIMER, &timeout, callback); + if(!descriptor) { + iohandler_log(IOLOG_ERROR, "could not allocate memory for IODescriptor in %s:%d", __FILE__, __LINE__); + return NULL; + } + descriptor->constant_timeout = msec; + iohandler_log(IOLOG_DEBUG, "added timer descriptor (sec: %d; usec: %d)", timeout.tv_sec, timeout.tv_usec); + return descriptor; +} + struct IODescriptor *iohandler_connect(const char *hostname, unsigned int port, int ssl, const char *bindhost, iohandler_callback *callback) { return iohandler_connect_flags(hostname, port, ssl, bindhost, callback, IOHANDLER_CONNECT_IPV4 | IOHANDLER_CONNECT_IPV6); } diff --git a/src/IOHandler.h b/src/IOHandler.h index 003f9b0..eb32cdc 100644 --- a/src/IOHandler.h +++ b/src/IOHandler.h @@ -82,6 +82,7 @@ struct IODescriptor { enum IOType type; enum IOStatus state; struct timeval timeout; + int constant_timeout; iohandler_callback *callback; struct IOBuffer readbuf; struct IOBuffer writebuf; @@ -120,6 +121,7 @@ void iohandler_set(int setting, int value); struct IODescriptor *iohandler_add(int sockfd, enum IOType type, struct timeval *timeout, iohandler_callback *callback); struct IODescriptor *iohandler_timer(struct timeval timeout, iohandler_callback *callback); +struct IODescriptor *iohandler_constant_timer(int msec, iohandler_callback *callback); struct IODescriptor *iohandler_connect(const char *hostname, unsigned int port, int ssl, const char *bind, iohandler_callback *callback); struct IODescriptor *iohandler_connect_flags(const char *hostname, unsigned int port, int ssl, const char *bindhost, iohandler_callback *callback, int flags); struct IODescriptor *iohandler_listen(const char *hostname, unsigned int port, iohandler_callback *callback); diff --git a/src/test/timer/iotest.c b/src/test/timer/iotest.c index 7ce2d44..17a91ec 100644 --- a/src/test/timer/iotest.c +++ b/src/test/timer/iotest.c @@ -26,7 +26,7 @@ static IOHANDLER_LOG_BACKEND(io_log); static struct timeval test_clock1, test_clock2; static int timercount; -static void add_timer(int ms) { +void add_timer(int ms) { struct timeval timeout; gettimeofday(&timeout, NULL); timeout.tv_usec += (ms % 1000) * 1000; @@ -45,7 +45,8 @@ int main(int argc, char *argv[]) { gettimeofday(&test_clock1, NULL); gettimeofday(&test_clock2, NULL); - add_timer(TEST_DURATION); + //add_timer(TEST_DURATION); + iohandler_constant_timer(TEST_DURATION, io_callback); timercount = 0; printf("[timer 0] %ld.%ld\n", test_clock1.tv_sec, test_clock1.tv_usec); @@ -61,7 +62,7 @@ static IOHANDLER_CALLBACK(io_callback) { double diff2; switch(event->type) { case IOEVENT_TIMEOUT: - add_timer(TEST_DURATION); + //add_timer(TEST_DURATION); timercount++; gettimeofday(&curr_time, NULL); diff1 = (curr_time.tv_sec - test_clock1.tv_sec) * 1000 + ((curr_time.tv_usec - test_clock1.tv_usec) / 1000); -- 2.20.1