From 2db77cda56947d4ee0f913c8082f6607855ca713 Mon Sep 17 00:00:00 2001 From: brain Date: Wed, 2 Apr 2008 17:08:09 +0000 Subject: Automatic detection and allocation of max fds. No longer needs recompile to change, just adjust it in your kernel or whatever and restart insp. Please note that select and iocp socket engines do not support detection and are always set to FD_SETSIZE and 10240 descriptors respectively. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@9263 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/socketengines/socketengine_epoll.cpp | 35 +++++++++++++++++++++++++------ src/socketengines/socketengine_iocp.cpp | 3 +++ src/socketengines/socketengine_kqueue.cpp | 34 +++++++++++++++++++++++------- src/socketengines/socketengine_ports.cpp | 34 ++++++++++++++++++++++++------ src/socketengines/socketengine_select.cpp | 15 ++++++++----- 5 files changed, 97 insertions(+), 24 deletions(-) (limited to 'src/socketengines') diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp index 1a0c5d53e..a749208d1 100644 --- a/src/socketengines/socketengine_epoll.cpp +++ b/src/socketengines/socketengine_epoll.cpp @@ -15,10 +15,11 @@ #include "exitcodes.h" #include #include "socketengines/socketengine_epoll.h" +#include EPollEngine::EPollEngine(InspIRCd* Instance) : SocketEngine(Instance) { - EngineHandle = epoll_create(MAX_DESCRIPTORS); + EngineHandle = epoll_create(GetMaxFds()); if (EngineHandle == -1) { @@ -29,17 +30,24 @@ EPollEngine::EPollEngine(InspIRCd* Instance) : SocketEngine(Instance) 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->Logs->Log("SOCKET",DEBUG,"Out of range FD"); return false; @@ -83,7 +91,7 @@ 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)) return false; struct epoll_event ev; @@ -107,19 +115,34 @@ bool EPollEngine::DelFd(EventHandler* eh, bool force) 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; diff --git a/src/socketengines/socketengine_iocp.cpp b/src/socketengines/socketengine_iocp.cpp index 5bc1faed4..b27f96035 100644 --- a/src/socketengines/socketengine_iocp.cpp +++ b/src/socketengines/socketengine_iocp.cpp @@ -32,6 +32,8 @@ IOCPEngine::IOCPEngine(InspIRCd * Instance) : SocketEngine(Instance) /* Null variables out. */ CurrentSetSize = 0; EngineHandle = 0; + MAX_DESCRIPTORS = 10240; + ref = new EventHandler* [10240]; memset(ref, 0, sizeof(EventHandler*) * MAX_DESCRIPTORS); } @@ -40,6 +42,7 @@ IOCPEngine::~IOCPEngine() /* Clean up winsock and close completion port */ CloseHandle(m_completionPort); WSACleanup(); + delete[] ref; } bool IOCPEngine::AddFd(EventHandler* eh) diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp index f245830de..63a1844cb 100644 --- a/src/socketengines/socketengine_kqueue.cpp +++ b/src/socketengines/socketengine_kqueue.cpp @@ -6,7 +6,7 @@ * See: http://www.inspircd.org/wiki/index.php/Credits * * This program is free but copyrighted software; see - * the file COPYING for details. + * the file COPYING for details. * * --------------------------------------------------- */ @@ -17,11 +17,13 @@ #include #include #include "socketengines/socketengine_kqueue.h" - +#include KQueueEngine::KQueueEngine(InspIRCd* Instance) : SocketEngine(Instance) { this->RecoverFromFork(); + ref = new EventHandler* [GetMaxFds()]; + ke_list = new struct kevent[GetMaxFds()]; } void KQueueEngine::RecoverFromFork() @@ -41,18 +43,21 @@ void KQueueEngine::RecoverFromFork() ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE); } CurrentSetSize = 0; + memset(ref, 0, GetMaxFds() * sizeof(EventHandler*)); } KQueueEngine::~KQueueEngine() { this->Close(EngineHandle); + delete[] ref; + delete[] ke_list; } bool KQueueEngine::AddFd(EventHandler* eh) { int fd = eh->GetFd(); - if ((fd < 0) || (fd > MAX_DESCRIPTORS)) + if ((fd < 0) || (fd > GetMaxFds() - 1)) return false; if (GetRemainingFds() <= 1) @@ -81,7 +86,7 @@ bool KQueueEngine::DelFd(EventHandler* eh, bool force) { int fd = eh->GetFd(); - if ((fd < 0) || (fd > MAX_DESCRIPTORS)) + if ((fd < 0) || (fd > GetMaxFds() - 1)) return false; struct kevent ke; @@ -116,12 +121,27 @@ void KQueueEngine::WantWrite(EventHandler* eh) int KQueueEngine::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 KQueueEngine::GetRemainingFds() { - return MAX_DESCRIPTORS - CurrentSetSize; + return GetMaxFds() - CurrentSetSize; } int KQueueEngine::DispatchEvents() @@ -129,7 +149,7 @@ int KQueueEngine::DispatchEvents() ts.tv_nsec = 0; ts.tv_sec = 1; - int i = kevent(EngineHandle, NULL, 0, &ke_list[0], MAX_DESCRIPTORS, &ts); + int i = kevent(EngineHandle, NULL, 0, &ke_list[0], GetMaxFds(), &ts); TotalEvents += i; diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp index 767ea0df0..113c6794e 100644 --- a/src/socketengines/socketengine_ports.cpp +++ b/src/socketengines/socketengine_ports.cpp @@ -6,7 +6,7 @@ * See: http://www.inspircd.org/wiki/index.php/Credits * * This program is free but copyrighted software; see - * the file COPYING for details. + * the file COPYING for details. * * --------------------------------------------------- */ @@ -15,6 +15,7 @@ #include "exitcodes.h" #include #include "socketengines/socketengine_ports.h" +#include PortsEngine::PortsEngine(InspIRCd* Instance) : SocketEngine(Instance) { @@ -29,17 +30,23 @@ PortsEngine::PortsEngine(InspIRCd* Instance) : SocketEngine(Instance) ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE); } CurrentSetSize = 0; + + ref = new EventHandler* [GetMaxFds()]; + events = new port_event_t[GetMaxFds()]; + memset(ref, 0, GetMaxFds() * sizeof(EventHandler*)); } PortsEngine::~PortsEngine() { this->Close(EngineHandle); + delete[] ref; + delete[] events; } bool PortsEngine::AddFd(EventHandler* eh) { int fd = eh->GetFd(); - if ((fd < 0) || (fd > MAX_DESCRIPTORS)) + if ((fd < 0) || (fd > GetMaxFds() - 1)) return false; if (GetRemainingFds() <= 1) @@ -64,7 +71,7 @@ void PortsEngine::WantWrite(EventHandler* eh) bool PortsEngine::DelFd(EventHandler* eh, bool force) { int fd = eh->GetFd(); - if ((fd < 0) || (fd > MAX_DESCRIPTORS)) + if ((fd < 0) || (fd > GetMaxFds() - 1)) return false; port_dissociate(EngineHandle, PORT_SOURCE_FD, fd); @@ -78,12 +85,27 @@ bool PortsEngine::DelFd(EventHandler* eh, bool force) int PortsEngine::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); + } +#include } int PortsEngine::GetRemainingFds() { - return MAX_DESCRIPTORS - CurrentSetSize; + return GetMaxFds() - CurrentSetSize; } int PortsEngine::DispatchEvents() @@ -94,7 +116,7 @@ int PortsEngine::DispatchEvents() poll_time.tv_nsec = 0; unsigned int nget = 1; // used to denote a retrieve request. - int i = port_getn(EngineHandle, this->events, MAX_DESCRIPTORS, &nget, &poll_time); + int i = port_getn(EngineHandle, this->events, GetMaxFds() - 1, &nget, &poll_time); // first handle an error condition if (i == -1) diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp index 055637890..5a5d61147 100644 --- a/src/socketengines/socketengine_select.cpp +++ b/src/socketengines/socketengine_select.cpp @@ -6,7 +6,7 @@ * See: http://www.inspircd.org/wiki/index.php/Credits * * This program is free but copyrighted software; see - * the file COPYING for details. + * the file COPYING for details. * * --------------------------------------------------- */ @@ -22,17 +22,22 @@ SelectEngine::SelectEngine(InspIRCd* Instance) : SocketEngine(Instance) { EngineHandle = 0; CurrentSetSize = 0; + + writeable = new bool [GetMaxFds()]; memset(writeable, 0, sizeof(writeable)); + ref = new EventHandler* [GetMaxFds()]; + memset(ref, 0, GetMaxFds() * sizeof(EventHandler*)); } SelectEngine::~SelectEngine() { + delete[] ref; } bool SelectEngine::AddFd(EventHandler* eh) { int fd = eh->GetFd(); - if ((fd < 0) || (fd > MAX_DESCRIPTORS)) + if ((fd < 0) || (fd > GetMaxFds() - 1)) return false; if (GetRemainingFds() <= 1) @@ -58,7 +63,7 @@ bool SelectEngine::DelFd(EventHandler* eh, bool force) { int fd = eh->GetFd(); - if ((fd < 0) || (fd > MAX_DESCRIPTORS)) + if ((fd < 0) || (fd > GetMaxFds() - 1)) return false; std::map::iterator t = fds.find(fd); @@ -79,7 +84,7 @@ int SelectEngine::GetMaxFds() int SelectEngine::GetRemainingFds() { - return FD_SETSIZE - CurrentSetSize; + return GetMaxFds() - CurrentSetSize; } int SelectEngine::DispatchEvents() @@ -87,7 +92,7 @@ int SelectEngine::DispatchEvents() int result = 0; timeval tval; int sresult = 0; - EventHandler* ev[MAX_DESCRIPTORS]; + EventHandler* ev[GetMaxFds()]; socklen_t codesize; int errcode; -- cgit v1.2.3