[IOMultiplexer] added auto-reloading timers
authorpk910 <philipp@zoelle1.de>
Sat, 17 Nov 2012 16:53:10 +0000 (17:53 +0100)
committerpk910 <philipp@zoelle1.de>
Sat, 17 Nov 2012 16:53:10 +0000 (17:53 +0100)
src/IOEngine_epoll.c
src/IOEngine_kevent.c
src/IOEngine_select.c
src/IOEngine_win32.c
src/IOHandler.c
src/IOHandler.h
src/test/timer/iotest.c

index e36394960f3af206bf4fa594fc10732e2de324f1..d1c139f6970f734a4fdb65ef2b9d5dde12e50e30 100644 (file)
@@ -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;
index f729dbbe820694181ee43d4ebf6dda7b7c9bfb47..ee93f8645f09f63a25cb750df661d70b91c3d535 100644 (file)
@@ -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;
index 48d7fed5c4a6b40898addb2b5247f11ea615bf5c..aff5fb920f264e47caa8ce9a86772cb7fcf0a6dd 100644 (file)
@@ -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;
index bce6fc14da687edf98597f061b2547dacde2593f..e29f8e57ae1e765fdb2656b38b102b07fe822ffd 100644 (file)
@@ -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--;
index 07cd794e9be73afb33dba2eccb065369f4d5e5e1..b2a391bf11e68388112f107a56747f84f6e8cde2 100644 (file)
@@ -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);
 }
index 003f9b0608ff2ba5b3f642ce47b349616f612d58..eb32cdc71ab345ca8961e4e411b72acfa8064cef 100644 (file)
@@ -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);
index 7ce2d44e6acc872b4ef0137b53b0840b06741274..17a91ecff13017a4967057330e57b421f8586c61 100644 (file)
@@ -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);