Commit 82b4cb57ed25967e43e965fdd02c93f8a89e3ab8

Authored by Georg Hopp
1 parent 2885147e

add epoll communication manager

... ... @@ -2,6 +2,7 @@ nobase_include_HEADERS = trcomm.h \
2 2 tr/comm_end_point.h \
3 3 tr/comm_manager.h \
4 4 tr/comm_manager_poll.h \
  5 + tr/comm_manager_epoll.h \
5 6 tr/connect_entry_point.h \
6 7 tr/connection.h \
7 8 tr/connector.h \
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2014 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#ifndef __TR_COMM_MANAGER_EPOLL_H__
  24 +#define __TR_COMM_MANAGER_EPOLL_H__
  25 +
  26 +#include <sys/types.h>
  27 +
  28 +#include "trbase.h"
  29 +#include "trevent.h"
  30 +
  31 +TR_CLASS(TR_CommManagerEpoll) {
  32 + TR_EXTENDS(TR_CommManager);
  33 +
  34 + int handle;
  35 +};
  36 +TR_INSTANCE_INIT(TR_CommManagerEpoll);
  37 +TR_CLASSVARS_DECL(TR_CommManagerEpoll) {
  38 + TR_CV_EXTENDS(TR_EventHandler);
  39 +};
  40 +
  41 +#endif // __TR_COMM_MANAGER_EPOLL_H__
  42 +
  43 +// vim: set ts=4 sw=4:
  44 +
... ...
... ... @@ -4,6 +4,7 @@
4 4 #include "tr/comm_end_point.h"
5 5 #include "tr/comm_manager.h"
6 6 #include "tr/comm_manager_poll.h"
  7 +#include "tr/comm_manager_epoll.h"
7 8 #include "tr/connect_entry_point.h"
8 9 #include "tr/connection.h"
9 10 #include "tr/connector.h"
... ...
... ... @@ -11,6 +11,7 @@ TRCOMM = cep_append_read_data.c \
11 11 comm_end_point.c \
12 12 comm_manager.c \
13 13 comm_manager_poll.c \
  14 + comm_manager_epoll.c \
14 15 comm_manager_shutdown.c \
15 16 conn_entry_point.c \
16 17 connection.c \
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2014 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#include <unistd.h>
  24 +#include <poll.h>
  25 +#include <sys/epoll.h>
  26 +
  27 +#include "trbase.h"
  28 +#include "trevent.h"
  29 +
  30 +#include "tr/comm_manager.h"
  31 +#include "tr/comm_manager_epoll.h"
  32 +#include "tr/interface/comm_manager.h"
  33 +#include "tr/comm_end_point.h"
  34 +#include "tr/connection.h"
  35 +#include "tr/connect_entry_point.h"
  36 +
  37 +#define MAXEVENTS 64
  38 +
  39 +struct epoll_event events[64];
  40 +
  41 +static
  42 +int
  43 +commManagerEpollCtor(void * _this, va_list * params)
  44 +{
  45 + TR_CommManagerEpoll this = _this;
  46 + TR_CommManager cmgr = _this;
  47 +
  48 + TR_PARENTCALL(TR_CommManagerEpoll, _this, TR_Class, ctor, params);
  49 + this->handle = epoll_create(cmgr->n_endpoints);
  50 +
  51 + return 0;
  52 +}
  53 +
  54 +static
  55 +void
  56 +commManagerEpollDtor(void * _this)
  57 +{
  58 + TR_CommManagerEpoll this = _this;
  59 +
  60 + close(this->handle);
  61 +}
  62 +
  63 +static
  64 +void
  65 +TR_commManagerEpollAddEndpoint(void * _this, TR_CommEndPoint endpoint)
  66 +{
  67 + TR_CommManagerEpoll this = _this;
  68 + struct epoll_event event;
  69 +
  70 + event.data.ptr = endpoint;
  71 + event.events = EPOLLIN | EPOLLET;
  72 +
  73 + epoll_ctl(this->handle, EPOLL_CTL_ADD, endpoint->transport->handle, &event);
  74 +}
  75 +
  76 +static
  77 +void
  78 +TR_commManagerEpollSelect(void * _this, TR_Event event, int timeout)
  79 +{
  80 + TR_CommManagerEpoll this = _this;
  81 + int i, nevents;
  82 +
  83 + nevents = epoll_wait(this->handle, events, MAXEVENTS, timeout);
  84 +
  85 + for (i=0; i<nevents; i++) {
  86 + TR_CommEndPoint endpoint = (TR_CommEndPoint)events[i].data.ptr;
  87 +
  88 + if ((events[i].events & POLLIN) == POLLIN) {
  89 + TR_Event event;
  90 +
  91 + if (TR_INSTANCE_OF(TR_TcpSocket, endpoint->transport)
  92 + && ((TR_TcpSocket)endpoint->transport)->listen) {
  93 + event = TR_eventSubjectEmit(
  94 + (TR_EventSubject)endpoint,
  95 + TR_CET_EVENT_ACC_READY,
  96 + NULL);
  97 + } else {
  98 + event = TR_eventSubjectEmit(
  99 + (TR_EventSubject)endpoint,
  100 + TR_CEP_EVENT_READ_READY,
  101 + NULL);
  102 + }
  103 +
  104 + TR_eventHandlerIssueEvent((TR_EventHandler)this, event);
  105 + }
  106 +
  107 + if ((events[i].events & POLLOUT) == POLLOUT) {
  108 + TR_eventHandlerIssueEvent(
  109 + (TR_EventHandler)this,
  110 + TR_eventSubjectEmit(
  111 + (TR_EventSubject)endpoint,
  112 + TR_CEP_EVENT_WRITE_READY,
  113 + NULL));
  114 + }
  115 + }
  116 +}
  117 +
  118 +static
  119 +void
  120 +TR_commManagerEpollEnableWrite(void * _this, TR_Event event)
  121 +{
  122 + TR_CommManagerEpoll this = _this;
  123 + TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject;
  124 +
  125 + if (! TR_socketFinWr(endpoint->transport)) {
  126 + struct epoll_event epevent;
  127 +
  128 + epevent.data.ptr = endpoint;
  129 + epevent.events = EPOLLOUT | EPOLLIN | EPOLLET;
  130 +
  131 + epoll_ctl(
  132 + this->handle,
  133 + EPOLL_CTL_MOD,
  134 + endpoint->transport->handle,
  135 + &epevent);
  136 + }
  137 +}
  138 +
  139 +static
  140 +void
  141 +TR_commManagerEpollDisableWrite(void * _this, TR_Event event)
  142 +{
  143 + TR_CommManagerEpoll this = _this;
  144 + TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject;
  145 + struct epoll_event epevent;
  146 +
  147 + epevent.data.ptr = endpoint;
  148 + epevent.events = EPOLLIN | EPOLLET;
  149 +
  150 + epoll_ctl(
  151 + this->handle,
  152 + EPOLL_CTL_MOD,
  153 + endpoint->transport->handle,
  154 + &epevent);
  155 +}
  156 +
  157 +static
  158 +void
  159 +TR_commManagerEpollClose(void * _this, TR_Event event)
  160 +{
  161 + TR_CommManagerEpoll this = _this;
  162 + TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject;
  163 +
  164 + epoll_ctl(this->handle, EPOLL_CTL_DEL, endpoint->transport->handle, NULL);
  165 +}
  166 +
  167 +static
  168 +void
  169 +TR_commManagerEpollEnableRead(void * _this, TR_Event event)
  170 +{
  171 +}
  172 +
  173 +static
  174 +void
  175 +TR_commManagerEpollDisableRead(void * _this, TR_Event event)
  176 +{
  177 +}
  178 +
  179 +static
  180 +void
  181 +TR_commManagerEpollCvInit(TR_class_ptr cls) {
  182 + TR_INHERIT_CLASSVARS(TR_CommManagerEpoll, TR_CommManager);
  183 +}
  184 +
  185 +TR_INIT_IFACE(TR_Class, commManagerEpollCtor, commManagerEpollDtor, NULL);
  186 +TR_INIT_IFACE(
  187 + TR_CommManager,
  188 + TR_commManagerEpollAddEndpoint,
  189 + TR_commManagerEpollSelect,
  190 + TR_commManagerEpollEnableWrite,
  191 + TR_commManagerEpollDisableWrite,
  192 + TR_commManagerEpollEnableRead,
  193 + TR_commManagerEpollClose,
  194 + TR_commManagerEpollDisableRead,
  195 + TR_commManagerEpollDisableWrite);
  196 +TR_CREATE_CLASS(
  197 + TR_CommManagerEpoll,
  198 + TR_CommManager,
  199 + TR_commManagerEpollCvInit,
  200 + TR_IF(TR_Class),
  201 + TR_IF(TR_CommManager));
  202 +
  203 +// vim: set ts=4 sw=4:
... ...
... ... @@ -31,6 +31,7 @@
31 31 #include "tr/server.h"
32 32 #include "tr/comm_manager.h"
33 33 #include "tr/comm_manager_poll.h"
  34 +#include "tr/comm_manager_epoll.h"
34 35 #include "tr/connector.h"
35 36 #include "tr/io_handler.h"
36 37 #include "tr/protocol_handler.h"
... ... @@ -42,7 +43,7 @@ serverCtor(void * _this, va_list * params)
42 43 {
43 44 TR_Server this = _this;
44 45
45   - this->comm_manager = (TR_CommManager)TR_new(TR_CommManagerPoll);
  46 + this->comm_manager = (TR_CommManager)TR_new(TR_CommManagerEpoll);
46 47 this->dispatcher = TR_new(TR_EventDispatcher, TR_EVD_SERVER, NULL, 100);
47 48 this->connector = TR_new(TR_Connector);
48 49 this->io_handler = TR_new(TR_IoHandler);
... ...
Please register or login to post a comment