diff --git a/.gitignore b/.gitignore
index 8c695b4..05a0350 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,5 +40,8 @@ test-driver
/assets/html/_documentation.html
tags
/trcomm.h*
-/testers/testserver*
-/testers/testclient*
+/testers/testserver
+/testers/testserver2
+/testers/testserver_thread
+/testers/testudp
+/testers/testtcp
diff --git a/include/Makefile.am b/include/Makefile.am
index 38ac4a6..ad401f9 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -18,5 +18,5 @@ nobase_include_HEADERS = trcomm.h \
tr/simple_client.h \
tr/interface/comm_end_point.h \
tr/interface/comm_manager.h \
- tr/interface/protocol.h
-
+ tr/interface/protocol.h \
+ tr/threaded_server.h
diff --git a/include/tr/threaded_server.h b/include/tr/threaded_server.h
new file mode 100644
index 0000000..8d63a18
--- /dev/null
+++ b/include/tr/threaded_server.h
@@ -0,0 +1,47 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2014 Georg Hopp
+ *
+ * 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 .
+ */
+
+#ifndef __TR_THREADED_SERVER_H__
+#define __TR_THREADED_SERVER_H__
+
+#include
+
+#include "trbase.h"
+#include "trevent.h"
+
+#include "tr/server.h"
+
+TR_CLASS(TR_ThreadedServer) {
+ TR_EXTENDS(TR_Server);
+
+ TR_EventThread * threads;
+ size_t n_threads;
+};
+TR_INSTANCE_INIT(TR_ThreadedServer);
+TR_CLASSVARS_DECL(TR_ThreadedServer) {};
+
+void TR_threadedServerStart(TR_ThreadedServer, unsigned long);
+
+#endif // __TR_THREADED_SERVER_H__
+
+// vim: set ts=4 sw=4:
+
diff --git a/include/trcomm.h b/include/trcomm.h
index b2691f9..a27fa16 100644
--- a/include/trcomm.h
+++ b/include/trcomm.h
@@ -21,6 +21,7 @@
#include "tr/interface/comm_end_point.h"
#include "tr/interface/comm_manager.h"
#include "tr/interface/protocol.h"
+#include "tr/threaded_server.h"
#endif // __TR_COMM_H__
diff --git a/src/Makefile.am b/src/Makefile.am
index 235169a..b29d062 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,6 +25,8 @@ TRCOMM = cet_accept.c \
protocol_message_raw.c \
protocol_raw.c \
server.c \
+ threaded_server.c \
+ threaded_server_start.c \
server_bind_tcp.c \
server_bind_udp.c \
server_start.c \
diff --git a/src/comm_manager.c b/src/comm_manager.c
index 3f893a4..7f2545c 100644
--- a/src/comm_manager.c
+++ b/src/comm_manager.c
@@ -103,6 +103,8 @@ static
void
commManagerCvInit(TR_class_ptr cls)
{
+ TR_CLASSVARS(TR_EventHandler, cls)->event_methods->tree = TR_new(TR_Tree);
+
TR_EVENT_HANDLER_SET_METHOD(
cls, TR_EventDispatcher,
TR_DISPATCHER_EVENT_DATA_WAIT,
diff --git a/src/connector.c b/src/connector.c
index a3bc9ce..2875d2b 100644
--- a/src/connector.c
+++ b/src/connector.c
@@ -92,11 +92,13 @@ static
void
connectorCvInit(TR_class_ptr cls)
{
- TR_EVENT_HANDLER_SET_METHOD(
- cls,
- TR_ConnEntryPoint,
- TR_CET_EVENT_ACC_READY,
- connectorAccept);
+ TR_CLASSVARS(TR_EventHandler, cls)->event_methods->tree = TR_new(TR_Tree);
+
+ TR_EVENT_HANDLER_SET_METHOD(
+ cls,
+ TR_ConnEntryPoint,
+ TR_CET_EVENT_ACC_READY,
+ connectorAccept);
}
TR_INSTANCE(TR_Hash, connectorEventMethods);
diff --git a/src/io_handler.c b/src/io_handler.c
index 6232b11..b7b46d9 100644
--- a/src/io_handler.c
+++ b/src/io_handler.c
@@ -158,6 +158,8 @@ static
void
ioHandlerCvInit(TR_class_ptr cls)
{
+ TR_CLASSVARS(TR_EventHandler, cls)->event_methods->tree = TR_new(TR_Tree);
+
TR_EVENT_HANDLER_SET_METHOD(
cls,
TR_CommEndPoint,
diff --git a/src/protocol_handler.c b/src/protocol_handler.c
index 9b58874..e4c841c 100644
--- a/src/protocol_handler.c
+++ b/src/protocol_handler.c
@@ -125,6 +125,8 @@ static
void
protocolHandlerCvInit(TR_class_ptr cls)
{
+ TR_CLASSVARS(TR_EventHandler, cls)->event_methods->tree = TR_new(TR_Tree);
+
TR_EVENT_HANDLER_SET_METHOD(
cls,
TR_CommEndPoint,
diff --git a/src/simple_client.c b/src/simple_client.c
index dd70237..d11693b 100644
--- a/src/simple_client.c
+++ b/src/simple_client.c
@@ -135,6 +135,8 @@ static
void
simpleClientCvInit(TR_class_ptr cls)
{
+ TR_CLASSVARS(TR_EventHandler, cls)->event_methods->tree = TR_new(TR_Tree);
+
TR_EVENT_HANDLER_SET_METHOD(
cls,
TR_EventDispatcher,
diff --git a/src/threaded_server.c b/src/threaded_server.c
new file mode 100644
index 0000000..d652238
--- /dev/null
+++ b/src/threaded_server.c
@@ -0,0 +1,71 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2014 Georg Hopp
+ *
+ * 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 .
+ */
+
+#include
+
+#include
+
+#include "trbase.h"
+#include "trio.h"
+#include "trevent.h"
+
+#include "tr/threaded_server.h"
+
+static
+int
+threadedServerCtor(void * _this, va_list * params)
+{
+ TR_ThreadedServer this = _this;
+ int i;
+
+ TR_PARENTCALL(TR_ThreadedServer, _this, TR_Class, ctor, params);
+
+ this->n_threads = va_arg(*params, size_t);
+ this->threads = TR_malloc(sizeof(TR_EventThread) * this->n_threads);
+
+ for (i=0; in_threads; i++) {
+ this->threads[i] = TR_new(
+ TR_EventThread,
+ ((TR_Server)this)->dispatcher);
+ }
+
+ return 0;
+}
+
+static
+void
+threadedServerDtor(void * _this)
+{
+ TR_ThreadedServer this = _this;
+ int i;
+
+ for (i=0; in_threads; i++) {
+ TR_delete(this->threads[i]);
+ }
+
+ TR_PARENTCALL(TR_ThreadedServer, _this, TR_Class, dtor);
+}
+
+TR_INIT_IFACE(TR_Class, threadedServerCtor, threadedServerDtor, NULL);
+TR_CREATE_CLASS(TR_ThreadedServer, TR_Server, NULL, TR_IF(TR_Class));
+
+// vim: set ts=4 sw=4:
diff --git a/src/threaded_server_start.c b/src/threaded_server_start.c
new file mode 100644
index 0000000..9bfe7d2
--- /dev/null
+++ b/src/threaded_server_start.c
@@ -0,0 +1,44 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2014 Georg Hopp
+ *
+ * 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 .
+ */
+
+#include "trbase.h"
+#include "trevent.h"
+
+#include "tr/threaded_server.h"
+
+void
+TR_threadedServerStart(TR_ThreadedServer this, unsigned long heartbeat)
+{
+ int i;
+
+ TR_eventDispatcherSetHeartbeat(((TR_Server)this)->dispatcher, heartbeat);
+
+ for (i=0; in_threads; i++) {
+ TR_eventThreadStart(this->threads[i]);
+ }
+
+ for (i=0; in_threads; i++) {
+ TR_eventThreadJoin(this->threads[i]);
+ }
+}
+
+// vim: set ts=4 sw=4:
diff --git a/testers/build.sh b/testers/build.sh
index 829a188..0b33782 100755
--- a/testers/build.sh
+++ b/testers/build.sh
@@ -7,3 +7,4 @@ gcc ${CFLAGS} -I/usr/local/include -L/usr/local/lib ${LIBS} -o testserver testse
gcc ${CFLAGS} -I/usr/local/include -L/usr/local/lib ${LIBS} -o testserver2 testserver2.c test_handler.o ${TRLIBS}
gcc ${CFLAGS} -I/usr/local/include -L/usr/local/lib ${LIBS} -o testtcp testclient.c ${TRLIBS}
gcc ${CFLAGS} -I/usr/local/include -L/usr/local/lib ${LIBS} -DUDP=1 -o testudp testclient.c ${TRLIBS}
+gcc ${CFLAGS} -I/usr/local/include -L/usr/local/lib ${LIBS} -lpthread -o testserver_thread testserver_thread.c test_handler.o ${TRLIBS}
diff --git a/testers/test_handler.c b/testers/test_handler.c
index cea3c69..47524cc 100644
--- a/testers/test_handler.c
+++ b/testers/test_handler.c
@@ -98,6 +98,8 @@ static
void
testHandlerCvInit(TR_class_ptr class)
{
+ TR_CLASSVARS(TR_EventHandler, class)->event_methods->tree = TR_new(TR_Tree);
+
TR_EVENT_HANDLER_SET_METHOD(
class,
TR_EventDispatcher,
diff --git a/testers/testclient.c b/testers/testclient.c
index 58f0961..91fb0d6 100644
--- a/testers/testclient.c
+++ b/testers/testclient.c
@@ -31,6 +31,7 @@ main (int argc, char * argv[])
int i, j=0;
TR_logger = TR_INSTANCE_CAST(TR_Logger, mylogger2);
+
protocol = TR_new(TR_ProtocolRaw);
#if UDP
socket = TR_new(TR_UdpSocket, TR_logger, "127.0.0.1", 5678, 0);
@@ -56,7 +57,7 @@ main (int argc, char * argv[])
message = (TR_ProtoMessageRaw)TR_simpleClientIssue(
client,
(TR_ProtoMessage)message,
- 100);
+ 100000000000000000);
if (! message) break;
#if 0
diff --git a/testers/testserver_thread.c b/testers/testserver_thread.c
new file mode 100644
index 0000000..5c4fd61
--- /dev/null
+++ b/testers/testserver_thread.c
@@ -0,0 +1,44 @@
+#include
+#include
+#include
+
+#include "trbase.h"
+#include "trcomm.h"
+#include "trio.h"
+#include "trevent.h"
+
+#include "test_handler.h"
+
+TR_INSTANCE(TR_LoggerSyslog, mylogger, {TR_LOGGER_INFO});
+TR_INSTANCE(TR_LoggerStderr, mylogger2, {TR_LOGGER_INFO});
+
+int
+main (int argc, char * argv[])
+{
+ TR_ThreadedServer server = TR_new(TR_ThreadedServer, 2);
+ TR_Protocol protocol = TR_new(TR_ProtocolRaw);
+ TestHandler test_handler = TR_new(TestHandler);
+
+ //TR_logger = TR_INSTANCE_CAST(TR_Logger, mylogger2);
+
+ TR_serverAddHandler((TR_Server)server, (TR_EventHandler)test_handler);
+ TR_serverBindTcp((TR_Server)server, "0.0.0.0", 5678, protocol);
+ TR_serverBindUdp((TR_Server)server, "0.0.0.0", 5678, protocol);
+
+ TR_threadedServerStart(server, 1000);
+
+ puts("cleanup...");
+
+ TR_delete(server);
+ TR_delete(test_handler);
+ TR_delete(protocol);
+
+ TR_eventHandlerClassCleanup(TestHandler);
+ TR_serverClassCleanup();
+
+ TR_cleanup();
+
+ return 0;
+}
+
+// vim: set ts=4 sw=4: