1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd: (C) 2002-2008 InspIRCd Development Team
6 * See: http://www.inspircd.org/wiki/index.php/Credits
8 * This program is free but copyrighted software; see
9 * the file COPYING for details.
11 * ---------------------------------------------------
15 #include "exitcodes.h"
16 #include "socketengines/socketengine_poll.h"
18 PollEngine::PollEngine(InspIRCd* Instance) : SocketEngine(Instance)
20 // Poll requires no special setup (which is nice).
23 ref = new EventHandler* [GetMaxFds()];
24 events = new struct epoll_event[GetMaxFds()];
26 memset(&events, 0, GetMaxFds() * sizeof(struct pollfds*));
29 PollEngine::~PollEngine()
31 // No destruction required, either.
36 bool PollEngine::AddFd(EventHandler* eh)
39 if ((fd < 0) || (fd > GetMaxFds() - 1))
41 ServerInstance->Logs->Log("SOCKET",DEBUG,"AddFd out of range: (fd: %d, max: %d)", fd, GetMaxFds());
45 if (GetRemainingFds() <= 1)
47 ServerInstance->Logs->Log("SOCKET",DEBUG,"No remaining FDs cannot add fd: %d", fd);
53 ServerInstance->Logs->Log("SOCKET",DEBUG,"Attempt to add duplicate fd: %d", fd);
61 events[fd]->events = POLLIN;
65 events[fd]->events = POLLOUT;
68 ServerInstance->Log(DEBUG,"New file descriptor: %d (%d)", fd, events[fd]->events);
73 void PollEngine::WantWrite(EventHandler* eh)
75 events[eh->GetFd()]->events = POLLIN | POLLOUT;
78 bool PollEngine::DelFd(EventHandler* eh, bool force)
81 if ((fd < 0) || (fd > MAX_DESCRIPTORS))
83 ServerInstance->Logs->Log("SOCKET",DEBUG,"DelFd out of range: (fd: %d, max: %d)", fd, GetMaxFds());
88 events[fd]->events = 0;
93 ServerInstance->Log(DEBUG,"Remove file descriptor: %d", fd);
97 int PollEngine::GetMaxFds()
100 return MAX_DESCRIPTORS;
102 int max = ulimit(4, 0);
105 MAX_DESCRIPTORS = max;
110 ServerInstance->Logs->Log("SOCKET", DEFAULT, "ERROR: Can't determine maximum number of open sockets!");
111 printf("ERROR: Can't determine maximum number of open sockets!\n");
112 ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE);
117 int PollEngine::GetRemainingFds()
119 return MAX_DESCRIPTORS - CurrentSetSize;
122 int PollEngine::DispatchEvents()
124 int i = poll(events, GetMaxFds() - 1, 1000);
126 socklen_t codesize = sizeof(int);
132 for (fd = 0; fd < GetMaxFds() - 1 && processed != i; fd++)
134 if (events[fd].revents)
137 if (events[fd].revents & POLLHUP)
140 ref[fd]->HandleEvent(EVENT_ERROR, 0);
144 if (events[fd].revents & POLLERR)
147 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0)
150 ref[fd]->HandleEvent(EVENT_ERROR, errcode);
154 if (events[fd].revents & POLLOUT)
156 // Switch to wanting read again
157 // event handlers have to request to write again if they need it
158 events[fd].events = POLLIN;
162 ref[fd]->HandleEvent(EVENT_WRITE);
165 if (events[fd].revents & POLLIN)
168 ref[fd]->HandleEvent(EVENT_READ);
176 std::string PollEngine::GetName()