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"
17 #include "socketengines/socketengine_ports.h"
20 PortsEngine::PortsEngine(InspIRCd* Instance) : SocketEngine(Instance)
22 EngineHandle = port_create();
24 if (EngineHandle == -1)
26 ServerInstance->Logs->Log("SOCKET",SPARSE,"ERROR: Could not initialize socket engine: %s", strerror(errno));
27 ServerInstance->Logs->Log("SOCKET",SPARSE,"ERROR: This is a fatal error, exiting now.");
28 printf("ERROR: Could not initialize socket engine: %s\n", strerror(errno));
29 printf("ERROR: This is a fatal error, exiting now.\n");
30 ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE);
34 ref = new EventHandler* [GetMaxFds()];
35 events = new port_event_t[GetMaxFds()];
36 memset(ref, 0, GetMaxFds() * sizeof(EventHandler*));
39 PortsEngine::~PortsEngine()
41 this->Close(EngineHandle);
46 bool PortsEngine::AddFd(EventHandler* eh)
49 if ((fd < 0) || (fd > GetMaxFds() - 1))
52 if (GetRemainingFds() <= 1)
59 port_associate(EngineHandle, PORT_SOURCE_FD, fd, eh->Readable() ? POLLRDNORM : POLLWRNORM, eh);
61 ServerInstance->Logs->Log("SOCKET",DEBUG,"New file descriptor: %d", fd);
66 void PortsEngine::WantWrite(EventHandler* eh)
68 port_associate(EngineHandle, PORT_SOURCE_FD, eh->GetFd(), POLLWRNORM, eh);
71 bool PortsEngine::DelFd(EventHandler* eh, bool force)
74 if ((fd < 0) || (fd > GetMaxFds() - 1))
77 port_dissociate(EngineHandle, PORT_SOURCE_FD, fd);
82 ServerInstance->Logs->Log("SOCKET",DEBUG,"Remove file descriptor: %d", fd);
86 int PortsEngine::GetMaxFds()
89 return MAX_DESCRIPTORS;
91 int max = ulimit(4, 0);
94 MAX_DESCRIPTORS = max;
99 ServerInstance->Logs->Log("SOCKET", DEFAULT, "ERROR: Can't determine maximum number of open sockets!");
100 printf("ERROR: Can't determine maximum number of open sockets!\n");
101 ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE);
106 int PortsEngine::GetRemainingFds()
108 return GetMaxFds() - CurrentSetSize;
111 int PortsEngine::DispatchEvents()
113 struct timespec poll_time;
115 poll_time.tv_sec = 1;
116 poll_time.tv_nsec = 0;
118 unsigned int nget = 1; // used to denote a retrieve request.
119 int i = port_getn(EngineHandle, this->events, GetMaxFds() - 1, &nget, &poll_time);
121 // first handle an error condition
127 for (i = 0; i < nget; i++)
129 switch (this->events[i].portev_source)
133 int fd = this->events[i].portev_object;
136 // reinsert port for next time around
137 port_associate(EngineHandle, PORT_SOURCE_FD, fd, POLLRDNORM, ref[fd]);
138 if ((this->events[i].portev_events & POLLRDNORM))
142 ref[fd]->HandleEvent((this->events[i].portev_events & POLLRDNORM) ? EVENT_READ : EVENT_WRITE);
153 std::string PortsEngine::GetName()