X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsocketengines%2Fsocketengine_epoll.cpp;h=5552cccf6b2a9167f4f72f03b7445cbfa60ad682;hb=a3802dee4bdfcf3dc11df09c59e6ed1912fbadd9;hp=fc806e10c01c0c2f698c5e0b92986ff8a960a83d;hpb=44ff49b0b1cf85acf6f3894c13aa803b4384d6f5;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp index fc806e10c..5552cccf6 100644 --- a/src/socketengines/socketengine_epoll.cpp +++ b/src/socketengines/socketengine_epoll.cpp @@ -2,7 +2,7 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * InspIRCd: (C) 2002-2007 InspIRCd Development Team + * InspIRCd: (C) 2002-2008 InspIRCd Development Team * See: http://www.inspircd.org/wiki/index.php/Credits * * This program is free but copyrighted software; see @@ -15,41 +15,57 @@ #include "exitcodes.h" #include #include "socketengines/socketengine_epoll.h" +#include EPollEngine::EPollEngine(InspIRCd* Instance) : SocketEngine(Instance) { - EngineHandle = epoll_create(MAX_DESCRIPTORS); + MAX_DESCRIPTORS = 0; + // This is not a maximum, just a hint at the eventual number of sockets that may be polled. + EngineHandle = epoll_create(GetMaxFds() / 4); if (EngineHandle == -1) { - ServerInstance->Log(SPARSE,"ERROR: Could not initialize socket engine: %s", strerror(errno)); - ServerInstance->Log(SPARSE,"ERROR: Your kernel probably does not have the proper features. This is a fatal error, exiting now."); + ServerInstance->Logs->Log("SOCKET",DEFAULT, "ERROR: Could not initialize socket engine: %s", strerror(errno)); + ServerInstance->Logs->Log("SOCKET",DEFAULT, "ERROR: Your kernel probably does not have the proper features. This is a fatal error, exiting now."); printf("ERROR: Could not initialize socket engine: %s\n", strerror(errno)); printf("ERROR: Your kernel probably does not have the proper features. This is a fatal error, exiting now.\n"); ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE); } CurrentSetSize = 0; + + ref = new EventHandler* [GetMaxFds()]; + events = new struct epoll_event[GetMaxFds()]; + + memset(ref, 0, GetMaxFds() * sizeof(EventHandler*)); } EPollEngine::~EPollEngine() { this->Close(EngineHandle); + delete[] ref; + delete[] events; } bool EPollEngine::AddFd(EventHandler* eh) { int fd = eh->GetFd(); - if ((fd < 0) || (fd > MAX_DESCRIPTORS)) + if ((fd < 0) || (fd > GetMaxFds() - 1)) { - ServerInstance->Log(DEBUG,"Out of range FD"); + ServerInstance->Logs->Log("SOCKET",DEBUG,"AddFd out of range: (fd: %d, max: %d)", fd, GetMaxFds()); return false; } if (GetRemainingFds() <= 1) + { + ServerInstance->Logs->Log("SOCKET",DEBUG,"No remaining FDs cannot add fd: %d", fd); return false; + } if (ref[fd]) + { + ServerInstance->Logs->Log("SOCKET",DEBUG,"Attempt to add duplicate fd: %d", fd); return false; + } struct epoll_event ev; memset(&ev,0,sizeof(struct epoll_event)); @@ -58,10 +74,11 @@ bool EPollEngine::AddFd(EventHandler* eh) int i = epoll_ctl(EngineHandle, EPOLL_CTL_ADD, fd, &ev); if (i < 0) { + ServerInstance->Logs->Log("SOCKET",DEBUG,"Error adding fd: %d to socketengine: %s", fd, strerror(errno)); return false; } - ServerInstance->Log(DEBUG,"New file descriptor: %d", fd); + ServerInstance->Logs->Log("SOCKET",DEBUG,"New file descriptor: %d", fd); ref[fd] = eh; CurrentSetSize++; @@ -83,8 +100,11 @@ void EPollEngine::WantWrite(EventHandler* eh) bool EPollEngine::DelFd(EventHandler* eh, bool force) { int fd = eh->GetFd(); - if ((fd < 0) || (fd > MAX_DESCRIPTORS)) + if ((fd < 0) || (fd > GetMaxFds() - 1)) + { + ServerInstance->Logs->Log("SOCKET",DEBUG,"DelFd out of range: (fd: %d, max: %d)", fd, GetMaxFds()); return false; + } struct epoll_event ev; memset(&ev,0,sizeof(struct epoll_event)); @@ -94,43 +114,62 @@ bool EPollEngine::DelFd(EventHandler* eh, bool force) if (i < 0 && !force) { - ServerInstance->Log(DEBUG,"Cant remove socket: %s", strerror(errno)); + ServerInstance->Logs->Log("SOCKET",DEBUG,"Cant remove socket: %s", strerror(errno)); return false; } ref[fd] = NULL; CurrentSetSize--; - ServerInstance->Log(DEBUG,"Remove file descriptor: %d", fd); + ServerInstance->Logs->Log("SOCKET",DEBUG,"Remove file descriptor: %d", fd); return true; } int EPollEngine::GetMaxFds() { - return MAX_DESCRIPTORS; + if (MAX_DESCRIPTORS) + return MAX_DESCRIPTORS; + + int max = ulimit(4, 0); + if (max > 0) + { + MAX_DESCRIPTORS = max; + return max; + } + else + { + ServerInstance->Logs->Log("SOCKET", DEFAULT, "ERROR: Can't determine maximum number of open sockets!"); + printf("ERROR: Can't determine maximum number of open sockets!\n"); + ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE); + } + return 0; } int EPollEngine::GetRemainingFds() { - return MAX_DESCRIPTORS - CurrentSetSize; + return GetMaxFds() - CurrentSetSize; } int EPollEngine::DispatchEvents() { socklen_t codesize; int errcode; - int i = epoll_wait(EngineHandle, events, MAX_DESCRIPTORS, 1000); + int i = epoll_wait(EngineHandle, events, GetMaxFds() - 1, 1000); + + TotalEvents += i; for (int j = 0; j < i; j++) { if (events[j].events & EPOLLHUP) { + ErrorEvents++; if (ref[events[j].data.fd]) ref[events[j].data.fd]->HandleEvent(EVENT_ERROR, 0); continue; } if (events[j].events & EPOLLERR) { + ErrorEvents++; /* Get error number */ if (getsockopt(events[j].data.fd, SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0) errcode = errno; @@ -140,6 +179,7 @@ int EPollEngine::DispatchEvents() } if (events[j].events & EPOLLOUT) { + WriteEvents++; struct epoll_event ev; memset(&ev,0,sizeof(struct epoll_event)); ev.events = EPOLLIN; @@ -150,6 +190,7 @@ int EPollEngine::DispatchEvents() } else { + ReadEvents++; if (ref[events[j].data.fd]) ref[events[j].data.fd]->HandleEvent(EVENT_READ); }