Browse Source

add epoll communication manager

1.0.0
Georg Hopp 11 years ago
parent
commit
82b4cb57ed
  1. 1
      include/Makefile.am
  2. 44
      include/tr/comm_manager_epoll.h
  3. 1
      include/trcomm.h
  4. 1
      src/Makefile.am
  5. 203
      src/comm_manager_epoll.c
  6. 3
      src/server.c

1
include/Makefile.am

@ -2,6 +2,7 @@ nobase_include_HEADERS = trcomm.h \
tr/comm_end_point.h \ tr/comm_end_point.h \
tr/comm_manager.h \ tr/comm_manager.h \
tr/comm_manager_poll.h \ tr/comm_manager_poll.h \
tr/comm_manager_epoll.h \
tr/connect_entry_point.h \ tr/connect_entry_point.h \
tr/connection.h \ tr/connection.h \
tr/connector.h \ tr/connector.h \

44
include/tr/comm_manager_epoll.h

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef __TR_COMM_MANAGER_EPOLL_H__
#define __TR_COMM_MANAGER_EPOLL_H__
#include <sys/types.h>
#include "trbase.h"
#include "trevent.h"
TR_CLASS(TR_CommManagerEpoll) {
TR_EXTENDS(TR_CommManager);
int handle;
};
TR_INSTANCE_INIT(TR_CommManagerEpoll);
TR_CLASSVARS_DECL(TR_CommManagerEpoll) {
TR_CV_EXTENDS(TR_EventHandler);
};
#endif // __TR_COMM_MANAGER_EPOLL_H__
// vim: set ts=4 sw=4:

1
include/trcomm.h

@ -4,6 +4,7 @@
#include "tr/comm_end_point.h" #include "tr/comm_end_point.h"
#include "tr/comm_manager.h" #include "tr/comm_manager.h"
#include "tr/comm_manager_poll.h" #include "tr/comm_manager_poll.h"
#include "tr/comm_manager_epoll.h"
#include "tr/connect_entry_point.h" #include "tr/connect_entry_point.h"
#include "tr/connection.h" #include "tr/connection.h"
#include "tr/connector.h" #include "tr/connector.h"

1
src/Makefile.am

@ -11,6 +11,7 @@ TRCOMM = cep_append_read_data.c \
comm_end_point.c \ comm_end_point.c \
comm_manager.c \ comm_manager.c \
comm_manager_poll.c \ comm_manager_poll.c \
comm_manager_epoll.c \
comm_manager_shutdown.c \ comm_manager_shutdown.c \
conn_entry_point.c \ conn_entry_point.c \
connection.c \ connection.c \

203
src/comm_manager_epoll.c

@ -0,0 +1,203 @@
/**
* \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 <http://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#include <poll.h>
#include <sys/epoll.h>
#include "trbase.h"
#include "trevent.h"
#include "tr/comm_manager.h"
#include "tr/comm_manager_epoll.h"
#include "tr/interface/comm_manager.h"
#include "tr/comm_end_point.h"
#include "tr/connection.h"
#include "tr/connect_entry_point.h"
#define MAXEVENTS 64
struct epoll_event events[64];
static
int
commManagerEpollCtor(void * _this, va_list * params)
{
TR_CommManagerEpoll this = _this;
TR_CommManager cmgr = _this;
TR_PARENTCALL(TR_CommManagerEpoll, _this, TR_Class, ctor, params);
this->handle = epoll_create(cmgr->n_endpoints);
return 0;
}
static
void
commManagerEpollDtor(void * _this)
{
TR_CommManagerEpoll this = _this;
close(this->handle);
}
static
void
TR_commManagerEpollAddEndpoint(void * _this, TR_CommEndPoint endpoint)
{
TR_CommManagerEpoll this = _this;
struct epoll_event event;
event.data.ptr = endpoint;
event.events = EPOLLIN | EPOLLET;
epoll_ctl(this->handle, EPOLL_CTL_ADD, endpoint->transport->handle, &event);
}
static
void
TR_commManagerEpollSelect(void * _this, TR_Event event, int timeout)
{
TR_CommManagerEpoll this = _this;
int i, nevents;
nevents = epoll_wait(this->handle, events, MAXEVENTS, timeout);
for (i=0; i<nevents; i++) {
TR_CommEndPoint endpoint = (TR_CommEndPoint)events[i].data.ptr;
if ((events[i].events & POLLIN) == POLLIN) {
TR_Event event;
if (TR_INSTANCE_OF(TR_TcpSocket, endpoint->transport)
&& ((TR_TcpSocket)endpoint->transport)->listen) {
event = TR_eventSubjectEmit(
(TR_EventSubject)endpoint,
TR_CET_EVENT_ACC_READY,
NULL);
} else {
event = TR_eventSubjectEmit(
(TR_EventSubject)endpoint,
TR_CEP_EVENT_READ_READY,
NULL);
}
TR_eventHandlerIssueEvent((TR_EventHandler)this, event);
}
if ((events[i].events & POLLOUT) == POLLOUT) {
TR_eventHandlerIssueEvent(
(TR_EventHandler)this,
TR_eventSubjectEmit(
(TR_EventSubject)endpoint,
TR_CEP_EVENT_WRITE_READY,
NULL));
}
}
}
static
void
TR_commManagerEpollEnableWrite(void * _this, TR_Event event)
{
TR_CommManagerEpoll this = _this;
TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject;
if (! TR_socketFinWr(endpoint->transport)) {
struct epoll_event epevent;
epevent.data.ptr = endpoint;
epevent.events = EPOLLOUT | EPOLLIN | EPOLLET;
epoll_ctl(
this->handle,
EPOLL_CTL_MOD,
endpoint->transport->handle,
&epevent);
}
}
static
void
TR_commManagerEpollDisableWrite(void * _this, TR_Event event)
{
TR_CommManagerEpoll this = _this;
TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject;
struct epoll_event epevent;
epevent.data.ptr = endpoint;
epevent.events = EPOLLIN | EPOLLET;
epoll_ctl(
this->handle,
EPOLL_CTL_MOD,
endpoint->transport->handle,
&epevent);
}
static
void
TR_commManagerEpollClose(void * _this, TR_Event event)
{
TR_CommManagerEpoll this = _this;
TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject;
epoll_ctl(this->handle, EPOLL_CTL_DEL, endpoint->transport->handle, NULL);
}
static
void
TR_commManagerEpollEnableRead(void * _this, TR_Event event)
{
}
static
void
TR_commManagerEpollDisableRead(void * _this, TR_Event event)
{
}
static
void
TR_commManagerEpollCvInit(TR_class_ptr cls) {
TR_INHERIT_CLASSVARS(TR_CommManagerEpoll, TR_CommManager);
}
TR_INIT_IFACE(TR_Class, commManagerEpollCtor, commManagerEpollDtor, NULL);
TR_INIT_IFACE(
TR_CommManager,
TR_commManagerEpollAddEndpoint,
TR_commManagerEpollSelect,
TR_commManagerEpollEnableWrite,
TR_commManagerEpollDisableWrite,
TR_commManagerEpollEnableRead,
TR_commManagerEpollClose,
TR_commManagerEpollDisableRead,
TR_commManagerEpollDisableWrite);
TR_CREATE_CLASS(
TR_CommManagerEpoll,
TR_CommManager,
TR_commManagerEpollCvInit,
TR_IF(TR_Class),
TR_IF(TR_CommManager));
// vim: set ts=4 sw=4:

3
src/server.c

@ -31,6 +31,7 @@
#include "tr/server.h" #include "tr/server.h"
#include "tr/comm_manager.h" #include "tr/comm_manager.h"
#include "tr/comm_manager_poll.h" #include "tr/comm_manager_poll.h"
#include "tr/comm_manager_epoll.h"
#include "tr/connector.h" #include "tr/connector.h"
#include "tr/io_handler.h" #include "tr/io_handler.h"
#include "tr/protocol_handler.h" #include "tr/protocol_handler.h"
@ -42,7 +43,7 @@ serverCtor(void * _this, va_list * params)
{ {
TR_Server this = _this; TR_Server this = _this;
this->comm_manager = (TR_CommManager)TR_new(TR_CommManagerPoll);
this->comm_manager = (TR_CommManager)TR_new(TR_CommManagerEpoll);
this->dispatcher = TR_new(TR_EventDispatcher, TR_EVD_SERVER, NULL, 100); this->dispatcher = TR_new(TR_EventDispatcher, TR_EVD_SERVER, NULL, 100);
this->connector = TR_new(TR_Connector); this->connector = TR_new(TR_Connector);
this->io_handler = TR_new(TR_IoHandler); this->io_handler = TR_new(TR_IoHandler);

Loading…
Cancel
Save