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--;
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;
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--;
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;
*/
#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;
}
struct IODescriptor *iofd, *tmp_iofd;
struct timeval now, tdiff;
int select_result;
+ int timer_fix;
gettimeofday(&now, NULL);
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) {
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) {
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);
}
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--;
}
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) {
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;
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;
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--;
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())
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;
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;
}
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);
}
enum IOType type;
enum IOStatus state;
struct timeval timeout;
+ int constant_timeout;
iohandler_callback *callback;
struct IOBuffer readbuf;
struct IOBuffer writebuf;
#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);
*/
#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() {
}
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));
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) {
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;
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) {
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;
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);
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);
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);
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
+++ /dev/null
-
-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 $<
+++ /dev/null
-/* 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);
-}
--- /dev/null
+
+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 $<
--- /dev/null
+/* 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);
+}
--- /dev/null
+
+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 $<
--- /dev/null
+/* 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);
+}