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: