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)
23 EngineHandle = port_create();
25 if (EngineHandle == -1)
27 ServerInstance->Logs->Log("SOCKET",SPARSE,"ERROR: Could not initialize socket engine: %s", strerror(errno));
28 ServerInstance->Logs->Log("SOCKET",SPARSE,"ERROR: This is a fatal error, exiting now.");
29 printf("ERROR: Could not initialize socket engine: %s\n", strerror(errno));
30 printf("ERROR: This is a fatal error, exiting now.\n");
31 ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE);
35 ref = new EventHandler* [GetMaxFds()];
36 events = new port_event_t[GetMaxFds()];
37 memset(ref, 0, GetMaxFds() * sizeof(EventHandler*));
40 PortsEngine::~PortsEngine()
42 this->Close(EngineHandle);
47 bool PortsEngine::AddFd(EventHandler* eh)
50 if ((fd < 0) || (fd > GetMaxFds() - 1))
53 if (GetRemainingFds() <= 1)
60 port_associate(EngineHandle, PORT_SOURCE_FD, fd, eh->Readable() ? POLLRDNORM : POLLWRNORM, eh);
62 ServerInstance->Logs->Log("SOCKET",DEBUG,"New file descriptor: %d", fd);
67 void PortsEngine::WantWrite(EventHandler* eh)
69 port_associate(EngineHandle, PORT_SOURCE_FD, eh->GetFd(), POLLWRNORM, eh);
72 bool PortsEngine::DelFd(EventHandler* eh, bool force)
75 if ((fd < 0) || (fd > GetMaxFds() - 1))
78 port_dissociate(EngineHandle, PORT_SOURCE_FD, fd);
83 ServerInstance->Logs->Log("SOCKET",DEBUG,"Remove file descriptor: %d", fd);
87 int PortsEngine::GetMaxFds()
90 return MAX_DESCRIPTORS;
92 int max = ulimit(4, 0);
95 MAX_DESCRIPTORS = max;
100 ServerInstance->Logs->Log("SOCKET", DEFAULT, "ERROR: Can't determine maximum number of open sockets!");
101 printf("ERROR: Can't determine maximum number of open sockets!\n");
102 ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE);
107 int PortsEngine::GetRemainingFds()
109 return GetMaxFds() - CurrentSetSize;
112 int PortsEngine::DispatchEvents()
114 struct timespec poll_time;
116 poll_time.tv_sec = 1;
117 poll_time.tv_nsec = 0;
119 unsigned int nget = 1; // used to denote a retrieve request.
120 int i = port_getn(EngineHandle, this->events, GetMaxFds() - 1, &nget, &poll_time);
122 // first handle an error condition
128 for (i = 0; i < nget; i++)
130 switch (this->events[i].portev_source)
134 int fd = this->events[i].portev_object;
137 // reinsert port for next time around
138 port_associate(EngineHandle, PORT_SOURCE_FD, fd, POLLRDNORM, ref[fd]);
139 if ((this->events[i].portev_events & POLLRDNORM))
143 ref[fd]->HandleEvent((this->events[i].portev_events & POLLRDNORM) ? EVENT_READ : EVENT_WRITE);
154 std::string PortsEngine::GetName()