Merge remote-tracking branch 'IOMultiplexer.git/master' into development
authorpk910 <philipp@zoelle1.de>
Mon, 17 Dec 2012 17:34:01 +0000 (18:34 +0100)
committerpk910 <philipp@zoelle1.de>
Mon, 17 Dec 2012 17:34:01 +0000 (18:34 +0100)
13 files changed:
src/IOEngine_epoll.c
src/IOEngine_kevent.c
src/IOEngine_select.c
src/IOEngine_win32.c
src/IOHandler.c
src/IOHandler.h
src/IOHandler_SSL.c
src/test/Makefile [deleted file]
src/test/iotest.c [deleted file]
src/test/socket/Makefile [new file with mode: 0644]
src/test/socket/iotest.c [new file with mode: 0644]
src/test/timer/Makefile [new file with mode: 0644]
src/test/timer/iotest.c [new file with mode: 0644]

index e363949..d1c139f 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 f729dbb..ee93f86 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 2d85d7c..aff5fb9 100644 (file)
@@ -16,6 +16,7 @@
  */
 #include "IOEngine.h"
 #include <errno.h>
+#include <time.h>
 #ifdef WIN32
 #define _WIN32_WINNT 0x501
 #include <windows.h>
 #include <stdio.h>
 #endif
 
+static int engine_select_timer_delay_fix;
+
 static int engine_select_init() {
-    /* empty */
+    engine_select_timer_delay_fix = 0;
     return 1;
 }
 
@@ -53,6 +56,7 @@ static void engine_select_loop(struct timeval *timeout) {
     struct IODescriptor *iofd, *tmp_iofd;
     struct timeval now, tdiff;
     int select_result;
+    int timer_fix;
     
     gettimeofday(&now, NULL);
     
@@ -60,6 +64,7 @@ static void engine_select_loop(struct timeval *timeout) {
     FD_ZERO(&read_fds);
     FD_ZERO(&write_fds);
     
+    select_result = 0;
     for(iofd = first_descriptor; iofd; iofd = tmp_iofd) {
         tmp_iofd = iofd->next;
         if(iofd->type == IOTYPE_STDIN) {
@@ -96,6 +101,7 @@ static void engine_select_loop(struct timeval *timeout) {
             if(iofd->fd > fds_size)
                 fds_size = iofd->fd;
             FD_SET(iofd->fd, &read_fds);
+            select_result++;
             #endif
         }
         else if(iofd->type == IOTYPE_SERVER || iofd->type == IOTYPE_CLIENT) {
@@ -104,6 +110,7 @@ static void engine_select_loop(struct timeval *timeout) {
             if(iofd->fd > fds_size)
                 fds_size = iofd->fd;
             FD_SET(iofd->fd, &read_fds);
+            select_result++;
             if(iohandler_wants_writes(iofd))
                 FD_SET(iofd->fd, &write_fds);
         }
@@ -113,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--;
@@ -122,13 +135,28 @@ static void engine_select_loop(struct timeval *timeout) {
         }
         if(timeval_is_smaler((&tdiff), timeout)) {
             timeout->tv_sec = tdiff.tv_sec;
-            timeout->tv_usec = tdiff.tv_usec;
+            timeout->tv_usec = tdiff.tv_usec + engine_select_timer_delay_fix;
+            if(timeout->tv_usec < 0) {
+                timeout->tv_sec--;
+                timeout->tv_usec += 1000000;
+            }
         }
         break;
     }
     
-    //select system call
-    select_result = select(fds_size + 1, &read_fds, &write_fds, NULL, timeout);
+    if(select_result) {
+        //select system call
+        select_result = select(fds_size + 1, &read_fds, &write_fds, NULL, timeout);
+    } else {
+        #ifdef WIN32
+        Sleep((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000) + 1);
+        #else
+        struct timespec usleep_time;
+        usleep_time.tv_sec = timeout->tv_sec;
+        usleep_time.tv_nsec = timeout->tv_usec * 1000;
+        nanosleep(&usleep_time, NULL);
+        #endif
+    }
     
     if (select_result < 0) {
         if (errno != EINTR) {
@@ -154,9 +182,20 @@ static void engine_select_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 <= 0)) {
-            iohandler_events(timer_priority, 0, 0);
-            iohandler_close(timer_priority); //also sets timer_priority to the next timed element
+        timer_fix = (tdiff.tv_sec * 1000000) + tdiff.tv_usec;
+        if(timer_fix <= 100) {
+            if(timer_fix + 100 < engine_select_timer_delay_fix || timer_fix - 100 > engine_select_timer_delay_fix) {
+                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);
+            }
+            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 bce6fc1..e29f8e5 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 52b27b3..b2a391b 100644 (file)
@@ -73,20 +73,30 @@ extern struct IOEngine engine_kevent;
 extern struct IOEngine engine_epoll;
 extern struct IOEngine engine_win32;
 
+int iohandler_settings = 0;
 struct IOEngine *engine = NULL;
 
+void iohandler_set(int setting, int value) {
+    if(value)
+        iohandler_settings |= setting;
+    else
+        iohandler_settings &= ~setting;
+}
+
 static void iohandler_init_engine() {
     if(engine) return;
     IOTHREAD_MUTEX_INIT(io_thread_sync);
     IOTHREAD_MUTEX_INIT(io_poll_sync);
     
     //try other engines
-    if(!engine && engine_kevent.init && engine_kevent.init())
-        engine = &engine_kevent;
-    if(!engine && engine_epoll.init && engine_epoll.init())
-        engine = &engine_epoll;
-    if(!engine && engine_win32.init && engine_win32.init())
-        engine = &engine_win32;
+    if(!(iohandler_settings & IOHANDLER_SETTING_HIGH_PRECISION_TIMER)) {
+        if(!engine && engine_kevent.init && engine_kevent.init())
+            engine = &engine_kevent;
+        if(!engine && engine_epoll.init && engine_epoll.init())
+            engine = &engine_epoll;
+        if(!engine && engine_win32.init && engine_win32.init())
+            engine = &engine_win32;
+    }
     
     if (!engine) {
         if(engine_select.init())
@@ -185,8 +195,13 @@ struct IODescriptor *iohandler_add(int sockfd, enum IOType type, struct timeval
     descriptor->type = type;
     descriptor->state = (type == IOTYPE_STDIN ? IO_CONNECTED : IO_CLOSED);
     descriptor->callback = callback;
-    if(timeout)
+    if(timeout) {
         descriptor->timeout = *timeout;
+        if(descriptor->timeout.tv_usec > 1000000) {
+            descriptor->timeout.tv_usec -= 1000000;
+            descriptor->timeout.tv_sec++;
+        }
+    }
     if(type != IOTYPE_TIMER) {
         descriptor->readbuf.buffer = malloc(IO_READ_BUFLEN + 2);
         descriptor->readbuf.bufpos = 0;
@@ -220,9 +235,20 @@ 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;
-    else {
+        if(descriptor->timeout.tv_usec > 1000000) {
+            descriptor->timeout.tv_usec -= 1000000;
+            descriptor->timeout.tv_sec++;
+        }
+    } else {
         descriptor->timeout.tv_sec = 0;
         descriptor->timeout.tv_usec = 0;
     }
@@ -249,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 9542985..82781d6 100644 (file)
@@ -83,6 +83,7 @@ struct IODescriptor {
     enum IOType type;
     enum IOStatus state;
     struct timeval timeout;
+    int constant_timeout;
     iohandler_callback *callback;
     struct IOBuffer readbuf;
     struct IOBuffer writebuf;
@@ -115,8 +116,13 @@ struct IOEvent {
 #define IOHANDLER_CONNECT_IPV4 0x01
 #define IOHANDLER_CONNECT_IPV6 0x02 /* overrides IOHANDLER_CONNECT_IPV4 */
 
+#define IOHANDLER_SETTING_HIGH_PRECISION_TIMER 0x01
+
+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 5d87cec..5408e97 100644 (file)
  */
 #include "IOEngine.h"
 #include "IOHandler_SSL.h"
+#ifdef HAVE_SSL
 
 void iohandler_ssl_init() {
-#ifdef HAVE_SSL
     SSL_library_init();
     OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
     SSL_load_error_strings();
-#endif
 }
 
 static void iohandler_ssl_error() {
@@ -33,7 +32,6 @@ static void iohandler_ssl_error() {
 }
 
 void iohandler_ssl_connect(struct IODescriptor *iofd) {
-#ifdef HAVE_SSL
     iofd->state = IO_SSLWAIT;
     iofd->ssl_server_hs = 0;
     struct IOSSLNode *sslnode = malloc(sizeof(*sslnode));
@@ -61,11 +59,9 @@ void iohandler_ssl_connect(struct IODescriptor *iofd) {
 ssl_connect_err:
     free(sslnode);
     iohandler_events(iofd, 0, 0);
-#endif    
 }
 
 void iohandler_ssl_listen(struct IODescriptor *iofd, const char *certfile, const char *keyfile) {
-#ifdef HAVE_SSL
     struct IOSSLNode *sslnode = malloc(sizeof(*sslnode));
     sslnode->sslContext = SSL_CTX_new(SSLv23_server_method());
     if(!sslnode->sslContext) {
@@ -97,11 +93,9 @@ ssl_listen_err:
     free(sslnode);
     iofd->sslnode = NULL;
     iohandler_events(iofd, 0, 0);
-#endif    
 }
 
 void iohandler_ssl_client_handshake(struct IODescriptor *iofd) {
-#ifdef HAVE_SSL
     // Perform an SSL handshake.
     int ret = SSL_do_handshake(iofd->sslnode->sslHandle);
     iofd->ssl_hs_read = 0;
@@ -126,11 +120,9 @@ void iohandler_ssl_client_handshake(struct IODescriptor *iofd) {
             iohandler_events(iofd, 0, 0);
             break;
     }
-#endif
 }
 
 void iohandler_ssl_client_accepted(struct IODescriptor *iofd, struct IODescriptor *client_iofd) {
-#ifdef HAVE_SSL
     struct IOSSLNode *sslnode = malloc(sizeof(*sslnode));
     sslnode->sslHandle = SSL_new(sslnode->sslContext);
     if(!sslnode->sslHandle) {
@@ -153,11 +145,9 @@ void iohandler_ssl_client_accepted(struct IODescriptor *iofd, struct IODescripto
 ssl_accept_err:
     iohandler_close(client_iofd);
     free(sslnode);
-#endif
 }
 
 void iohandler_ssl_server_handshake(struct IODescriptor *iofd) {
-#ifdef HAVE_SSL
     // Perform an SSL handshake.
     int ret = SSL_accept(iofd->sslnode->sslHandle);
     iofd->ssl_hs_read = 0;
@@ -182,11 +172,9 @@ void iohandler_ssl_server_handshake(struct IODescriptor *iofd) {
             iohandler_events(iofd, 0, 0);
             break;
     }
-#endif
 }
 
 void iohandler_ssl_disconnect(struct IODescriptor *iofd) {
-#ifdef HAVE_SSL
     if(!iofd->sslnode) return;
     SSL_shutdown(iofd->sslnode->sslHandle);
     SSL_free(iofd->sslnode->sslHandle);
@@ -194,11 +182,9 @@ void iohandler_ssl_disconnect(struct IODescriptor *iofd) {
     free(iofd->sslnode);
     iofd->sslnode = NULL;
     iofd->ssl_active = 0;
-#endif
 }
 
 int iohandler_ssl_read(struct IODescriptor *iofd, char *buffer, int len) {
-#ifdef HAVE_SSL
     if(!iofd->sslnode) return 0;
     int ret = SSL_read(iofd->sslnode->sslHandle, buffer, len);
     int update = (iofd->ssl_hs_read || iofd->ssl_hs_write);
@@ -230,12 +216,9 @@ int iohandler_ssl_read(struct IODescriptor *iofd, char *buffer, int len) {
             return -1;
             break;
     }
-#endif
-    return 0;
 }
 
 int iohandler_ssl_write(struct IODescriptor *iofd, char *buffer, int len) {
-#ifdef HAVE_SSL
     if(!iofd->sslnode) return 0;
     int ret = SSL_write(iofd->sslnode->sslHandle, buffer, len);
     int update = (iofd->ssl_hs_read || iofd->ssl_hs_write);
@@ -267,6 +250,18 @@ int iohandler_ssl_write(struct IODescriptor *iofd, char *buffer, int len) {
             return -1;
             break;
     }
-#endif
-    return 0;
 }
+
+#else
+// NULL-backend
+
+void iohandler_ssl_init() {};
+void iohandler_ssl_connect(struct IODescriptor *iofd) {};
+void iohandler_ssl_listen(struct IODescriptor *iofd, const char *certfile, const char *keyfile) {};
+void iohandler_ssl_client_handshake(struct IODescriptor *iofd) {};
+void iohandler_ssl_client_accepted(struct IODescriptor *iofd, struct IODescriptor *client_iofd) {};
+void iohandler_ssl_server_handshake(struct IODescriptor *iofd) {};
+void iohandler_ssl_disconnect(struct IODescriptor *iofd) {};
+int iohandler_ssl_read(struct IODescriptor *iofd, char *buffer, int len) { return 0; };
+int iohandler_ssl_write(struct IODescriptor *iofd, char *buffer, int len) { return 0; };
+#endif
diff --git a/src/test/Makefile b/src/test/Makefile
deleted file mode 100644 (file)
index 37fa3d8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-
-CC      = gcc
-CFLAGS  = -g -O0 -Wall -Wshadow -Werror -DHAVE_PTHREAD_H
-LDFLAGS = -lws2_32 -lpthread
-
-OBJ     = ../IOEngine_epoll.o ../IOEngine_kevent.o ../IOEngine_select.o ../IOEngine_win32.o ../IOHandler.o ../IOHandler_SSL.o iotest.o
-
-all: $(OBJ)
-       $(CC) $(CFLAGS) -oiotest $(OBJ) $(LDFLAGS)
-
-%.o: %.c
-       $(CC) $(CFLAGS) -o$@ -c $<
diff --git a/src/test/iotest.c b/src/test/iotest.c
deleted file mode 100644 (file)
index 15f32f4..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* main.c - IOMultiplexer
- * Copyright (C) 2012  Philipp Kreil (pk910)
- * 
- * 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
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License 
- * along with this program. If not, see <http://www.gnu.org/licenses/>. 
- */
-
-#include <stdio.h>
-#include "../IOHandler.h"
-
-static IOHANDLER_CALLBACK(io_callback);
-static IOHANDLER_LOG_BACKEND(io_log);
-
-static struct IODescriptor *irc_iofd = NULL;
-
-int main(int argc, char *argv[]) {
-    iolog_backend = io_log;
-    
-    irc_iofd = iohandler_connect("pk910.de", 6667, 0, NULL, io_callback);
-    
-    struct IODescriptor *iofd;
-    iofd = iohandler_add(0, IOTYPE_STDIN, NULL, io_callback);
-    iofd->read_lines = 1;
-    
-    while(1) {
-        iohandler_poll();
-    }
-}
-
-static IOHANDLER_CALLBACK(io_callback) {
-    switch(event->type) {
-        case IOEVENT_CONNECTED:
-            printf("[connect]\n");
-            break;
-        case IOEVENT_CLOSED:
-            printf("[disconnect]\n");
-            break;
-        case IOEVENT_RECV:
-            if(event->iofd->type == IOTYPE_STDIN) {
-                iohandler_printf(irc_iofd, "%s\n", event->data.recv_str);
-                printf("[out] %s\n", event->data.recv_str);
-            } else
-                printf("[in] %s\n", event->data.recv_str);
-            break;
-        
-        default:
-            break;
-    }
-}
-
-static IOHANDLER_LOG_BACKEND(io_log) {
-    //printf("%s", line);
-}
diff --git a/src/test/socket/Makefile b/src/test/socket/Makefile
new file mode 100644 (file)
index 0000000..724e34b
--- /dev/null
@@ -0,0 +1,12 @@
+
+CC      = gcc
+CFLAGS  = -g -O0 -Wall -Wshadow -Werror -DHAVE_PTHREAD_H
+LDFLAGS = -lws2_32 -lpthread
+
+OBJ     = ../../IOEngine_epoll.o ../../IOEngine_kevent.o ../../IOEngine_select.o ../../IOEngine_win32.o ../../IOHandler.o ../../IOHandler_SSL.o iotest.o
+
+all: $(OBJ)
+       $(CC) $(CFLAGS) -oiotest $(OBJ) $(LDFLAGS)
+
+%.o: %.c
+       $(CC) $(CFLAGS) -o$@ -c $<
diff --git a/src/test/socket/iotest.c b/src/test/socket/iotest.c
new file mode 100644 (file)
index 0000000..15f32f4
--- /dev/null
@@ -0,0 +1,63 @@
+/* main.c - IOMultiplexer
+ * Copyright (C) 2012  Philipp Kreil (pk910)
+ * 
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#include <stdio.h>
+#include "../IOHandler.h"
+
+static IOHANDLER_CALLBACK(io_callback);
+static IOHANDLER_LOG_BACKEND(io_log);
+
+static struct IODescriptor *irc_iofd = NULL;
+
+int main(int argc, char *argv[]) {
+    iolog_backend = io_log;
+    
+    irc_iofd = iohandler_connect("pk910.de", 6667, 0, NULL, io_callback);
+    
+    struct IODescriptor *iofd;
+    iofd = iohandler_add(0, IOTYPE_STDIN, NULL, io_callback);
+    iofd->read_lines = 1;
+    
+    while(1) {
+        iohandler_poll();
+    }
+}
+
+static IOHANDLER_CALLBACK(io_callback) {
+    switch(event->type) {
+        case IOEVENT_CONNECTED:
+            printf("[connect]\n");
+            break;
+        case IOEVENT_CLOSED:
+            printf("[disconnect]\n");
+            break;
+        case IOEVENT_RECV:
+            if(event->iofd->type == IOTYPE_STDIN) {
+                iohandler_printf(irc_iofd, "%s\n", event->data.recv_str);
+                printf("[out] %s\n", event->data.recv_str);
+            } else
+                printf("[in] %s\n", event->data.recv_str);
+            break;
+        
+        default:
+            break;
+    }
+}
+
+static IOHANDLER_LOG_BACKEND(io_log) {
+    //printf("%s", line);
+}
diff --git a/src/test/timer/Makefile b/src/test/timer/Makefile
new file mode 100644 (file)
index 0000000..724e34b
--- /dev/null
@@ -0,0 +1,12 @@
+
+CC      = gcc
+CFLAGS  = -g -O0 -Wall -Wshadow -Werror -DHAVE_PTHREAD_H
+LDFLAGS = -lws2_32 -lpthread
+
+OBJ     = ../../IOEngine_epoll.o ../../IOEngine_kevent.o ../../IOEngine_select.o ../../IOEngine_win32.o ../../IOHandler.o ../../IOHandler_SSL.o iotest.o
+
+all: $(OBJ)
+       $(CC) $(CFLAGS) -oiotest $(OBJ) $(LDFLAGS)
+
+%.o: %.c
+       $(CC) $(CFLAGS) -o$@ -c $<
diff --git a/src/test/timer/iotest.c b/src/test/timer/iotest.c
new file mode 100644 (file)
index 0000000..17a91ec
--- /dev/null
@@ -0,0 +1,81 @@
+/* main.c - IOMultiplexer
+ * Copyright (C) 2012  Philipp Kreil (pk910)
+ * 
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#include <stdio.h>
+#include "../../IOHandler.h"
+
+#define TEST_DURATION 100
+
+static IOHANDLER_CALLBACK(io_callback);
+static IOHANDLER_LOG_BACKEND(io_log);
+
+static struct timeval test_clock1, test_clock2;
+static int timercount;
+
+void add_timer(int ms) {
+    struct timeval timeout;
+    gettimeofday(&timeout, NULL);
+    timeout.tv_usec += (ms % 1000) * 1000;
+    timeout.tv_sec += (ms / 1000);
+    if(timeout.tv_usec > 1000000) {
+        timeout.tv_usec -= 1000000;
+        timeout.tv_sec++;
+    }
+    iohandler_timer(timeout, io_callback);
+}
+
+int main(int argc, char *argv[]) {
+    iolog_backend = io_log;
+    
+    iohandler_set(IOHANDLER_SETTING_HIGH_PRECISION_TIMER, 1);
+    
+    gettimeofday(&test_clock1, NULL);
+    gettimeofday(&test_clock2, NULL);
+    //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);
+    
+    while(1) {
+        iohandler_poll();
+    }
+}
+
+static IOHANDLER_CALLBACK(io_callback) {
+    struct timeval curr_time;
+    int diff1;
+    double diff2;
+    switch(event->type) {
+        case IOEVENT_TIMEOUT:
+            //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);
+            diff2 = (curr_time.tv_sec - test_clock2.tv_sec) * 1000 + ((curr_time.tv_usec - test_clock2.tv_usec) / 1000.0);
+            diff2 -= (timercount * TEST_DURATION);
+            gettimeofday(&test_clock1, NULL);
+            printf("[timer %03d] %ld.%06ld [%d ms]  accuracy: %f ms\n", timercount, curr_time.tv_sec, curr_time.tv_usec, diff1, diff2);
+            break;
+        default:
+            break;
+    }
+}
+
+static IOHANDLER_LOG_BACKEND(io_log) {
+    //printf("%s", line);
+}