src/IOHandler_test/client_ssl/Makefile
src/IOHandler_test/server_ssl/Makefile
src/IOHandler_test/timer/Makefile
+ src/IOHandler_test/timer++/Makefile
src/IOHandler_test/resolv/Makefile
])
AC_OUTPUT
--- /dev/null
+/* IOTimer.cpp - IOMultiplexer v2
+ * Copyright (C) 2014 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/>.
+ */
+extern "C" {
+ #include "../IOHandler/IOTimer.h"
+}
+#include "IOTimer.h"
+#include <cstdarg>
+#include <cstdio>
+#include <cstring>
+
+static IOTIMER_CALLBACK(c_timer_callback) {
+ CIOTimer *ciotimer = (CIOTimer *) iotimer->data;
+ ciotimer->timer_callback();
+}
+
+CIOTimer::CIOTimer() {
+ this->iotimer = iotimer_create(NULL);
+ this->iotimer->data = this;
+ iotimer_set_callback(this->iotimer, c_timer_callback);
+ iotimer_set_persistent(this->iotimer, 1);
+}
+
+CIOTimer::~CIOTimer() {
+ iotimer_destroy(this->iotimer);
+}
+
+void CIOTimer::setTimeout(timeval timeout) {
+ iotimer_set_timeout(this->iotimer, &timeout);
+}
+
+void CIOTimer::setRelativeTimeout(timeval timeout) {
+ timeval now;
+ gettimeofday(&now, NULL);
+
+ timeout.tv_sec += now.tv_sec;
+ timeout.tv_usec += now.tv_usec;
+ while(timeout.tv_usec > 1000000) {
+ timeout.tv_usec -= 1000000;
+ timeout.tv_sec++;
+ }
+
+ this->setTimeout(timeout);
+}
+
+void CIOTimer::setRelativeTimeout(timeval timeout, int auto_reload) {
+ this->setRelativeTimeout(timeout);
+ if(auto_reload)
+ this->setAutoReload(timeout);
+}
+
+void CIOTimer::setRelativeTimeoutSeconds(double seconds) {
+ this->setRelativeTimeoutSeconds(seconds, 0);
+}
+
+void CIOTimer::setRelativeTimeoutSeconds(double seconds, int auto_reload) {
+ timeval tout;
+ tout.tv_sec = (int) seconds;
+ tout.tv_usec = ((int) (seconds * 1000000)) % 1000000;
+ this->setRelativeTimeout(tout);
+ if(auto_reload)
+ this->setAutoReload(tout);
+}
+
+timeval CIOTimer::getTimeout() {
+ return iotimer_get_timeout(this->iotimer);
+}
+
+timeval CIOTimer::getRelativeTimeout() {
+ timeval tout, now;
+ gettimeofday(&now, NULL);
+
+ tout = iotimer_get_timeout(this->iotimer);
+
+ if(tout.tv_sec || tout.tv_usec) {
+ tout.tv_sec = tout.tv_sec - now.tv_sec;
+ tout.tv_usec = tout.tv_usec - now.tv_usec;
+ if(tout.tv_usec < 0) {
+ tout.tv_usec += 1000000;
+ tout.tv_sec--;
+ }
+ }
+
+ return tout;
+}
+
+double CIOTimer::getRelativeTimeoutSeconds() {
+ timeval tout = this->getRelativeTimeout();
+ return tout.tv_sec + (tout.tv_usec / 1000000);
+}
+
+
+void CIOTimer::setAutoReload(timeval timeout) {
+ iotimer_set_autoreload(this->iotimer, &timeout);
+}
+
+void CIOTimer::clearAutoReload() {
+ iotimer_set_autoreload(this->iotimer, NULL);
+}
+
+timeval CIOTimer::getAutoReloadTime() {
+ return iotimer_get_autoreload(this->iotimer);
+}
+
+int CIOTimer::getAutoReloadState() {
+ timeval timeout = this->getAutoReloadTime();
+ if(timeout.tv_sec == 0 && timeout.tv_usec == 0)
+ return 0;
+ else
+ return 1;
+}
+
+void CIOTimer::setActive(int active) {
+ if(active)
+ iotimer_start(this->iotimer);
+ else
+ iotimer_stop(this->iotimer);
+}
+
+int CIOTimer::getActive() {
+ return iotimer_state(this->iotimer);
+}
+
+void CIOTimer::timer_callback() {
+ this->timeout();
+}
+
--- /dev/null
+/* IOTimer.h - IOMultiplexer v2
+ * Copyright (C) 2014 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/>.
+ */
+#ifndef _IOTimer_cpp_h
+#define _IOTimer_cpp_h
+
+#include <iostream>
+#include <string>
+#include <sys/time.h>
+
+struct IOTimerDescriptor;
+
+class CIOTimer {
+public:
+ CIOTimer();
+ ~CIOTimer();
+
+ void setTimeout(timeval timeout);
+ timeval getTimeout();
+ void setRelativeTimeout(timeval timeout);
+ void setRelativeTimeout(timeval timeout, int auto_reload);
+ timeval getRelativeTimeout();
+ void setRelativeTimeoutSeconds(double seconds);
+ void setRelativeTimeoutSeconds(double seconds, int auto_reload);
+ double getRelativeTimeoutSeconds();
+
+ void setAutoReload(timeval timeout);
+ void clearAutoReload();
+ int getAutoReloadState();
+ timeval getAutoReloadTime();
+
+ void setActive(int active);
+ int getActive();
+
+
+ void timer_callback();
+protected:
+ virtual void timeout() {};
+
+private:
+ IOTimerDescriptor *iotimer;
+};
+
+#endif
libiohandler_cpp_la_LIBADD = ../IOHandler/libiohandler.la
libiohandler_cpp_la_SOURCES = IOHandler.cpp \
-IOSocket.cpp
+IOSocket.cpp \
+IOTimer.cpp
all-local: libiohandler.cpp.la
\ No newline at end of file
void iotimer_start(struct IOTimerDescriptor *descriptor) {
struct _IOTimerDescriptor *timer = descriptor->iotimer;
if(timer == NULL) {
- iolog_trigger(IOLOG_WARNING, "called iotimer_set_autoreload for destroyed IOTimerDescriptor in %s:%d", __FILE__, __LINE__);
+ iolog_trigger(IOLOG_WARNING, "called iotimer_start for destroyed IOTimerDescriptor in %s:%d", __FILE__, __LINE__);
return;
}
timer->flags |= IOTIMERFLAG_ACTIVE;
- if(!(timer->flags & IOTIMERFLAG_IN_LIST))
- _trigger_timer(timer);
+ _rearrange_timer(timer);
+}
+
+void iotimer_stop(struct IOTimerDescriptor *descriptor) {
+ struct _IOTimerDescriptor *timer = descriptor->iotimer;
+ if(timer == NULL) {
+ iolog_trigger(IOLOG_WARNING, "called iotimer_stop for destroyed IOTimerDescriptor in %s:%d", __FILE__, __LINE__);
+ return;
+ }
+ timer->flags &= ~IOTIMERFLAG_ACTIVE;
+ if((timer->flags & IOTIMERFLAG_PERSISTENT)) {
+ timer->flags &= ~IOTIMERFLAG_ACTIVE;
+ _rearrange_timer(timer);
+ } else
+ iotimer_destroy(descriptor);
+}
+
+int iotimer_state(struct IOTimerDescriptor *descriptor) {
+ struct _IOTimerDescriptor *timer = descriptor->iotimer;
+ if(timer == NULL) {
+ iolog_trigger(IOLOG_WARNING, "called iotimer_state for destroyed IOTimerDescriptor in %s:%d", __FILE__, __LINE__);
+ return 0;
+ }
+ if((timer->flags & IOTIMERFLAG_ACTIVE))
+ return 1;
+ else
+ return 0;
}
void iotimer_set_autoreload(struct IOTimerDescriptor *descriptor, struct timeval *autoreload) {
timer->flags |= IOTIMERFLAG_PERIODIC;
timer->autoreload = *autoreload;
- if(!(timer->flags & IOTIMERFLAG_IN_LIST)) {
+ if(timer->timeout.tv_sec == 0 && timer->timeout.tv_usec == 0) {
struct timeval now;
gettimeofday(&now, NULL);
timer->timeout = now;
}
}
+struct timeval iotimer_get_autoreload(struct IOTimerDescriptor *descriptor) {
+ struct _IOTimerDescriptor *timer = descriptor->iotimer;
+ if(timer == NULL) {
+ iolog_trigger(IOLOG_WARNING, "called iotimer_get_autoreload for destroyed IOTimerDescriptor in %s:%d", __FILE__, __LINE__);
+ struct timeval tout;
+ tout.tv_sec = 0;
+ tout.tv_usec = 0;
+ return tout;
+ }
+ if((timer->flags & IOTIMERFLAG_PERIODIC))
+ return timer->autoreload;
+ else {
+ struct timeval tout;
+ tout.tv_sec = 0;
+ tout.tv_usec = 0;
+ return tout;
+ }
+}
+
void iotimer_set_timeout(struct IOTimerDescriptor *descriptor, struct timeval *timeout) {
struct _IOTimerDescriptor *timer = descriptor->iotimer;
if(timer == NULL) {
_rearrange_timer(timer);
}
+struct timeval iotimer_get_timeout(struct IOTimerDescriptor *descriptor) {
+ struct _IOTimerDescriptor *timer = descriptor->iotimer;
+ if(timer == NULL) {
+ iolog_trigger(IOLOG_WARNING, "called iotimer_get_timeout for destroyed IOTimerDescriptor in %s:%d", __FILE__, __LINE__);
+ struct timeval tout;
+ tout.tv_sec = 0;
+ tout.tv_usec = 0;
+ return tout;
+ }
+ return timer->timeout;
+}
+
void iotimer_set_callback(struct IOTimerDescriptor *descriptor, iotimer_callback *callback) {
descriptor->callback = callback;
}
+void iotimer_set_persistent(struct IOTimerDescriptor *descriptor, int persistent) {
+ struct _IOTimerDescriptor *timer = descriptor->iotimer;
+ if(timer == NULL) {
+ iolog_trigger(IOLOG_WARNING, "called iotimer_set_persistent for destroyed IOTimerDescriptor in %s:%d", __FILE__, __LINE__);
+ return;
+ }
+ if(persistent)
+ timer->flags |= IOTIMERFLAG_PERSISTENT;
+ else
+ timer->flags &= ~IOTIMERFLAG_PERSISTENT;
+}
+
void iotimer_destroy(struct IOTimerDescriptor *descriptor) {
struct _IOTimerDescriptor *timer = descriptor->iotimer;
if(timer == NULL) {
iolog_trigger(IOLOG_ERROR, "could not allocate memory for _IOTimerDescriptor in %s:%d", __FILE__, __LINE__);
return NULL;
}
- if(timeout) {
+ if(timeout)
timer->timeout = *timeout;
- _rearrange_timer(timer);
- }
return timer;
}
timer->prev->next = timer->next;
if(timer->next != NULL)
timer->next->prev = timer->prev;
+ timer->flags &= ~IOTIMERFLAG_IN_LIST;
}
+ if(!(timer->flags & IOTIMERFLAG_ACTIVE))
+ return;
struct _IOTimerDescriptor *ctimer;
for(ctimer = iotimer_sorted_descriptors; ctimer; ctimer = ctimer->next) {
if(timeval_is_bigger(ctimer->timeout, timer->timeout)) {
void _trigger_timer() {
struct timeval now;
- _trigger_timer_start:
- gettimeofday(&now, NULL);
-
- struct _IOTimerDescriptor *timer = iotimer_sorted_descriptors;
- if(!timer || timeval_is_bigger(timer->timeout, now)) {
- return;
- }
- iotimer_sorted_descriptors = timer->next;
- if(timer->next != NULL)
- timer->next->prev = timer->prev;
- timer->flags &= ~IOTIMERFLAG_IN_LIST;
-
- if((timer->flags & IOTIMERFLAG_PERIODIC))
- _autoreload_timer(timer);
-
- if(timer->flags & IOTIMERFLAG_PARENT_PUBLIC) {
- struct IOTimerDescriptor *descriptor = timer->parent;
- if(descriptor->callback)
- descriptor->callback(descriptor);
- if(!(timer->flags & IOTIMERFLAG_PERIODIC))
- iotimer_destroy(descriptor);
- } else {
- if(!(timer->flags & IOTIMERFLAG_PERIODIC))
- _destroy_timer(timer);
+ struct _IOTimerDescriptor *timer;
+ while(iotimer_sorted_descriptors) {
+ gettimeofday(&now, NULL);
+
+ timer = iotimer_sorted_descriptors;
+ if(timeval_is_bigger(timer->timeout, now))
+ break;
+
+ iotimer_sorted_descriptors = timer->next;
+ if(timer->next != NULL)
+ timer->next->prev = timer->prev;
+ timer->flags &= ~IOTIMERFLAG_IN_LIST;
+
+ if((timer->flags & IOTIMERFLAG_PERIODIC))
+ _autoreload_timer(timer);
+
+ if(timer->flags & IOTIMERFLAG_PARENT_PUBLIC) {
+ struct IOTimerDescriptor *descriptor = timer->parent;
+ if(descriptor->callback)
+ descriptor->callback(descriptor);
+ if(!(timer->flags & IOTIMERFLAG_PERIODIC))
+ iotimer_destroy(descriptor);
+ } else {
+ if(!(timer->flags & IOTIMERFLAG_PERIODIC))
+ _destroy_timer(timer);
+ }
}
-
- goto _trigger_timer_start;
}
#define IOTIMERFLAG_IN_LIST 0x04
#define IOTIMERFLAG_PARENT_PUBLIC 0x08
#define IOTIMERFLAG_PARENT_SOCKET 0x10
+#define IOTIMERFLAG_PERSISTENT 0x20
struct _IOTimerDescriptor;
struct IOTimerDescriptor *iotimer_create(struct timeval *timeout);
void iotimer_start(struct IOTimerDescriptor *iotimer);
+void iotimer_stop(struct IOTimerDescriptor *iotimer);
+int iotimer_state(struct IOTimerDescriptor *iotimer);
void iotimer_set_autoreload(struct IOTimerDescriptor *iotimer, struct timeval *autoreload);
+struct timeval iotimer_get_autoreload(struct IOTimerDescriptor *iotimer);
void iotimer_set_timeout(struct IOTimerDescriptor *iotimer, struct timeval *timeout);
+struct timeval iotimer_get_timeout(struct IOTimerDescriptor *iotimer);
void iotimer_set_callback(struct IOTimerDescriptor *iotimer, iotimer_callback *callback);
+void iotimer_set_persistent(struct IOTimerDescriptor *iotimer, int persistent);
void iotimer_destroy(struct IOTimerDescriptor *iotimer);
#endif
##Process this file with automake to create Makefile.in
ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = client client++ client_ssl server_ssl timer resolv
+SUBDIRS = client client++ client_ssl server_ssl timer timer++ resolv
--- /dev/null
+.deps
+.libs
+*.o
+*.exe
+iotest
+Makefile
+Makefile.in
--- /dev/null
+##Process this file with automake to create Makefile.in
+ACLOCAL_AMFLAGS = -I m4
+
+noinst_PROGRAMS = iotest
+
+iotest_LDADD = ../../IOHandler++/libiohandler.cpp.la
+iotest_SOURCES = iotest.cpp
--- /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++/IOHandler.h"
+#include "../../IOHandler++/IOTimer.h"
+
+class IOTestTimer : public CIOTimer {
+public:
+ IOTestTimer(int test_duration) : CIOTimer() {
+ this->tick_count = 0;
+ this->test_duration = test_duration;
+ gettimeofday(&this->test_clock1, NULL);
+ gettimeofday(&this->test_clock2, NULL);
+
+ this->setRelativeTimeoutSeconds(this->test_duration / 1000.0, 1);
+ this->setActive(1);
+
+ printf("[timer 0] %ld.%ld\n", test_clock1.tv_sec, test_clock1.tv_usec);
+ };
+
+protected:
+ virtual void timeout() {
+ this->tick_count++;
+ this->tick();
+ };
+
+private:
+ timeval test_clock1, test_clock2;
+ int tick_count, test_duration;
+
+ void tick() {
+ timeval curr_time;
+ int diff1;
+ double diff2;
+
+ gettimeofday(&curr_time, NULL);
+ diff1 = (curr_time.tv_sec - this->test_clock1.tv_sec) * 1000 + ((curr_time.tv_usec - this->test_clock1.tv_usec) / 1000);
+ diff2 = (curr_time.tv_sec - this->test_clock2.tv_sec) * 1000 + ((curr_time.tv_usec - this->test_clock2.tv_usec) / 1000.0);
+ diff2 -= (this->tick_count * this->test_duration);
+ gettimeofday(&this->test_clock1, NULL);
+ printf("[timer %03d] %ld.%06ld [%d ms] accuracy: %f ms\n", this->tick_count, curr_time.tv_sec, curr_time.tv_usec, diff1, diff2);
+ };
+};
+
+
+int main(int argc, char *argv[]) {
+ CIOHandler *iohandler = new CIOHandler();
+ IOTestTimer *timer = new IOTestTimer(100);
+
+ iohandler->start();
+}