diff options
-rw-r--r-- | include/inspircd.h | 4 | ||||
-rw-r--r-- | include/socketengine.h | 64 | ||||
-rw-r--r-- | src/commands/cmd_dns.cpp | 8 | ||||
-rw-r--r-- | src/commands/cmd_stats.cpp | 6 | ||||
-rw-r--r-- | src/configreader.cpp | 4 | ||||
-rw-r--r-- | src/inspircd.cpp | 14 | ||||
-rw-r--r-- | src/inspsocket.cpp | 38 | ||||
-rw-r--r-- | src/listensocket.cpp | 6 | ||||
-rw-r--r-- | src/modules/extra/m_pgsql.cpp | 16 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_gnutls.cpp | 20 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_openssl.cpp | 20 | ||||
-rw-r--r-- | src/modules/m_httpd_stats.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_ident.cpp | 10 | ||||
-rw-r--r-- | src/modules/m_spanningtree/override_squit.cpp | 2 | ||||
-rw-r--r-- | src/socketengine.cpp | 37 | ||||
-rw-r--r-- | src/socketengines/socketengine_epoll.cpp | 48 | ||||
-rw-r--r-- | src/socketengines/socketengine_kqueue.cpp | 54 | ||||
-rw-r--r-- | src/socketengines/socketengine_poll.cpp | 48 | ||||
-rw-r--r-- | src/socketengines/socketengine_ports.cpp | 51 | ||||
-rw-r--r-- | src/socketengines/socketengine_select.cpp | 49 | ||||
-rw-r--r-- | src/threadengines/threadengine_pthread.cpp | 8 | ||||
-rw-r--r-- | src/usermanager.cpp | 4 | ||||
-rw-r--r-- | src/users.cpp | 2 |
23 files changed, 233 insertions, 282 deletions
diff --git a/include/inspircd.h b/include/inspircd.h index 6f9163ad8..930514169 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -334,10 +334,6 @@ class CoreExport InspIRCd */ CommandParser* Parser; - /** Socket engine, handles socket activity events - */ - SocketEngine* SE; - /** Thread engine, Handles threading where required */ ThreadEngine* Threads; diff --git a/include/socketengine.h b/include/socketengine.h index 6503ea293..305d389d4 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -165,6 +165,9 @@ class CoreExport EventHandler : public classbase private: /** Private state maintained by socket engine */ int event_mask; + + void SetEventMask(int mask) { event_mask = mask; } + protected: /** File descriptor. * All events which can be handled must have a file descriptor. This @@ -271,35 +274,34 @@ class CoreExport SocketEngine private: /** Reference table, contains all current handlers **/ - std::vector<EventHandler*> ref; + static std::vector<EventHandler*> ref; protected: /** Current number of descriptors in the engine */ - size_t CurrentSetSize; + static size_t CurrentSetSize; /** List of handlers that want a trial read/write */ - std::set<int> trials; + static std::set<int> trials; - int MAX_DESCRIPTORS; + static int MAX_DESCRIPTORS; /** Socket engine statistics: count of various events, bandwidth usage */ - Statistics stats; + static Statistics stats; - virtual void OnSetEvent(EventHandler* eh, int old_mask, int new_mask) = 0; - void SetEventMask(EventHandler* eh, int value); + static void OnSetEvent(EventHandler* eh, int old_mask, int new_mask); /** Add an event handler to the base socket engine. AddFd(EventHandler*, int) should call this. */ - bool AddFdRef(EventHandler* eh); + static bool AddFdRef(EventHandler* eh); - void DelFdRef(EventHandler* eh); + static void DelFdRef(EventHandler* eh); template <typename T> - void ResizeDouble(std::vector<T>& vect) + static void ResizeDouble(std::vector<T>& vect) { - if (CurrentSetSize > vect.size()) + if (SocketEngine::CurrentSetSize > vect.size()) vect.resize(vect.size() * 2); } @@ -311,14 +313,16 @@ public: * failure (for example, you try and enable * epoll on a 2.4 linux kernel) then this * function may bail back to the shell. + * @return void, but it is acceptable for this function to bail back to + * the shell or operating system on fatal error. */ - SocketEngine(); + static void Init(); /** Destructor. * The destructor transparently tidies up * any resources used by the socket engine. */ - virtual ~SocketEngine(); + static void Deinit(); /** Add an EventHandler object to the engine. Use AddFd to add a file * descriptor to the engine and have the socket engine monitor it. You @@ -327,7 +331,7 @@ public: * @param eh An event handling object to add * @param event_mask The initial event mask for the object */ - virtual bool AddFd(EventHandler* eh, int event_mask) = 0; + static bool AddFd(EventHandler* eh, int event_mask); /** If you call this function and pass it an * event handler, that event handler will @@ -340,17 +344,17 @@ public: * @param eh The event handler to change * @param event_mask The changes to make to the wait state */ - void ChangeEventMask(EventHandler* eh, int event_mask); + static void ChangeEventMask(EventHandler* eh, int event_mask); /** Returns the highest file descriptor you may store in the socket engine * @return The maximum fd value */ - inline int GetMaxFds() const { return MAX_DESCRIPTORS; } + static int GetMaxFds() { return MAX_DESCRIPTORS; } /** Returns the number of file descriptors being queried * @return The set size */ - inline size_t GetUsedFds() const { return CurrentSetSize; } + static size_t GetUsedFds() { return CurrentSetSize; } /** Delete an event handler from the engine. * This function call deletes an EventHandler @@ -360,21 +364,21 @@ public: * required you must do this yourself. * @param eh The event handler object to remove */ - virtual void DelFd(EventHandler* eh) = 0; + static void DelFd(EventHandler* eh); /** Returns true if a file descriptor exists in * the socket engine's list. * @param fd The event handler to look for * @return True if this fd has an event handler */ - virtual bool HasFd(int fd); + static bool HasFd(int fd); /** Returns the EventHandler attached to a specific fd. * If the fd isnt in the socketengine, returns NULL. * @param fd The event handler to look for * @return A pointer to the event handler, or NULL */ - virtual EventHandler* GetRef(int fd); + static EventHandler* GetRef(int fd); /** Waits for events and dispatches them to handlers. Please note that * this doesn't wait long, only a couple of milliseconds. It returns the @@ -384,17 +388,17 @@ public: * value. * @return The number of events which have occured. */ - virtual int DispatchEvents() = 0; + static int DispatchEvents(); /** Dispatch trial reads and writes. This causes the actual socket I/O * to happen when writes have been pre-buffered. */ - virtual void DispatchTrialWrites(); + static void DispatchTrialWrites(); /** Returns true if the file descriptors in the given event handler are * within sensible ranges which can be handled by the socket engine. */ - virtual bool BoundsCheckFd(EventHandler* eh); + static bool BoundsCheckFd(EventHandler* eh); /** Abstraction for BSD sockets accept(2). * This function should emulate its namesake system call exactly. @@ -427,7 +431,7 @@ public: * @param flags A flag value that controls the sending of the data. * @return This method should return exactly the same values as the system call it emulates. */ - int Send(EventHandler* fd, const void *buf, size_t len, int flags); + static int Send(EventHandler* fd, const void *buf, size_t len, int flags); /** Abstraction for BSD sockets recv(2). * This function should emulate its namesake system call exactly. @@ -437,7 +441,7 @@ public: * @param flags A flag value that controls the reception of the data. * @return This method should return exactly the same values as the system call it emulates. */ - int Recv(EventHandler* fd, void *buf, size_t len, int flags); + static int Recv(EventHandler* fd, void *buf, size_t len, int flags); /** Abstraction for BSD sockets recvfrom(2). * This function should emulate its namesake system call exactly. @@ -449,7 +453,7 @@ public: * @param fromlen The size of the from parameter. * @return This method should return exactly the same values as the system call it emulates. */ - int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen); + static int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen); /** Abstraction for BSD sockets sendto(2). * This function should emulate its namesake system call exactly. @@ -461,7 +465,7 @@ public: * @param tolen The size of the to parameter. * @return This method should return exactly the same values as the system call it emulates. */ - int SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen); + static int SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen); /** Abstraction for BSD sockets connect(2). * This function should emulate its namesake system call exactly. @@ -523,11 +527,11 @@ public: * @return void, but it is acceptable for this function to bail back to * the shell or operating system on fatal error. */ - virtual void RecoverFromFork(); + static void RecoverFromFork(); /** Get data transfer and event statistics */ - const Statistics& GetStats() const { return stats; } + static const Statistics& GetStats() { return stats; } /** Should we ignore the error in errno? * Checks EAGAIN and WSAEWOULDBLOCK @@ -555,5 +559,3 @@ inline bool SocketEngine::IgnoreError() return false; } - -SocketEngine* CreateSocketEngine(); diff --git a/src/commands/cmd_dns.cpp b/src/commands/cmd_dns.cpp index 4af8b2c9e..63924d87b 100644 --- a/src/commands/cmd_dns.cpp +++ b/src/commands/cmd_dns.cpp @@ -519,7 +519,7 @@ class MyManager : public Manager, public Timer, public EventHandler return; } - if (ServerInstance->SE->SendTo(this, buffer, len, 0, &this->myserver.sa, this->myserver.sa_size()) != len) + if (SocketEngine::SendTo(this, buffer, len, 0, &this->myserver.sa, this->myserver.sa_size()) != len) throw Exception("DNS: Unable to send query"); } @@ -567,7 +567,7 @@ class MyManager : public Manager, public Timer, public EventHandler irc::sockets::sockaddrs from; socklen_t x = sizeof(from); - int length = ServerInstance->SE->RecvFrom(this, buffer, sizeof(buffer), 0, &from.sa, &x); + int length = SocketEngine::RecvFrom(this, buffer, sizeof(buffer), 0, &from.sa, &x); if (length < Packet::HEADER_LENGTH) return; @@ -681,7 +681,7 @@ class MyManager : public Manager, public Timer, public EventHandler { if (this->GetFd() > -1) { - ServerInstance->SE->DelFd(this); + SocketEngine::DelFd(this); SocketEngine::Shutdown(this, 2); SocketEngine::Close(this); this->SetFd(-1); @@ -713,7 +713,7 @@ class MyManager : public Manager, public Timer, public EventHandler SocketEngine::Close(this); this->SetFd(-1); } - else if (!ServerInstance->SE->AddFd(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE)) + else if (!SocketEngine::AddFd(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE)) { ServerInstance->Logs->Log("RESOLVER", LOG_SPARSE, "Resolver: Internal error starting DNS - hostnames will NOT resolve."); SocketEngine::Close(this); diff --git a/src/commands/cmd_stats.cpp b/src/commands/cmd_stats.cpp index afcbe01e6..9510136ff 100644 --- a/src/commands/cmd_stats.cpp +++ b/src/commands/cmd_stats.cpp @@ -139,7 +139,7 @@ void CommandStats::DoStats(char statschar, User* user, string_list &results) for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++) { ConnectClass* c = *i; - results.push_back("215 "+user->nick+" i NOMATCH * "+c->GetHost()+" "+ConvToStr(c->limit ? c->limit : ServerInstance->SE->GetMaxFds())+" "+ConvToStr(idx)+" "+ServerInstance->Config->ServerName+" *"); + results.push_back("215 "+user->nick+" i NOMATCH * "+c->GetHost()+" "+ConvToStr(c->limit ? c->limit : SocketEngine::GetMaxFds())+" "+ConvToStr(idx)+" "+ServerInstance->Config->ServerName+" *"); results.push_back("218 "+user->nick+" Y "+ConvToStr(idx)+" "+ConvToStr(c->GetPingTime())+" 0 "+ConvToStr(c->GetSendqHardMax())+" :"+ ConvToStr(c->GetRecvqMax())+" "+ConvToStr(c->GetRegTimeout())); idx++; @@ -182,7 +182,7 @@ void CommandStats::DoStats(char statschar, User* user, string_list &results) break; case 'E': { - const SocketEngine::Statistics& stats = ServerInstance->SE->GetStats(); + const SocketEngine::Statistics& stats = SocketEngine::GetStats(); results.push_back("249 "+user->nick+" :Total events: "+ConvToStr(stats.TotalEvents)); results.push_back("249 "+user->nick+" :Read events: "+ConvToStr(stats.ReadEvents)); results.push_back("249 "+user->nick+" :Write events: "+ConvToStr(stats.WriteEvents)); @@ -212,7 +212,7 @@ void CommandStats::DoStats(char statschar, User* user, string_list &results) float kbitpersec_in, kbitpersec_out, kbitpersec_total; char kbitpersec_in_s[30], kbitpersec_out_s[30], kbitpersec_total_s[30]; - ServerInstance->SE->GetStats().GetBandwidth(kbitpersec_in, kbitpersec_out, kbitpersec_total); + SocketEngine::GetStats().GetBandwidth(kbitpersec_in, kbitpersec_out, kbitpersec_total); snprintf(kbitpersec_total_s, 30, "%03.5f", kbitpersec_total); snprintf(kbitpersec_out_s, 30, "%03.5f", kbitpersec_out); diff --git a/src/configreader.cpp b/src/configreader.cpp index 59a9f0d97..0cdfedf04 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -36,7 +36,7 @@ ServerConfig::ServerConfig() dns_timeout = 5; MaxTargets = 20; NetBufferSize = 10240; - SoftLimit = ServerInstance->SE->GetMaxFds(); + SoftLimit = SocketEngine::GetMaxFds(); MaxConn = SOMAXCONN; MaxChans = 20; OperMaxChans = 30; @@ -375,7 +375,7 @@ void ServerConfig::Fill() PrefixPart = options->getString("prefixpart"); SuffixPart = options->getString("suffixpart"); FixedPart = options->getString("fixedpart"); - SoftLimit = ConfValue("performance")->getInt("softlimit", ServerInstance->SE->GetMaxFds(), 10, ServerInstance->SE->GetMaxFds()); + SoftLimit = ConfValue("performance")->getInt("softlimit", SocketEngine::GetMaxFds(), 10, SocketEngine::GetMaxFds()); CCOnConnect = ConfValue("performance")->getBool("clonesonconnect", true); MaxConn = ConfValue("performance")->getInt("somaxconn", SOMAXCONN); XLineMessage = options->getString("xlinemessage", options->getString("moronbanner", "You're banned!")); diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 7cc66cd5f..101df432f 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -142,7 +142,7 @@ void InspIRCd::Cleanup() DeleteZero(this->PI); DeleteZero(this->Threads); DeleteZero(this->Timers); - DeleteZero(this->SE); + SocketEngine::Deinit(); Logs->CloseLogs(); DeleteZero(this->Logs); } @@ -285,7 +285,7 @@ InspIRCd::InspIRCd(int argc, char** argv) : // This must be created first, so other parts of Insp can use it while starting up this->Logs = new LogManager; - SE = CreateSocketEngine(); + SocketEngine::Init(); this->Threads = new ThreadEngine; @@ -457,7 +457,7 @@ InspIRCd::InspIRCd(int argc, char** argv) : } } - SE->RecoverFromFork(); + SocketEngine::RecoverFromFork(); /* During startup we read the configuration now, not in * a seperate thread @@ -504,7 +504,7 @@ InspIRCd::InspIRCd(int argc, char** argv) : std::cout << std::endl << "Hint: Try using a public IP instead of blank or *" << std::endl; } - std::cout << "InspIRCd is now running as '" << Config->ServerName << "'[" << Config->GetSID() << "] with " << SE->GetMaxFds() << " max open sockets" << std::endl; + std::cout << "InspIRCd is now running as '" << Config->ServerName << "'[" << Config->GetSID() << "] with " << SocketEngine::GetMaxFds() << " max open sockets" << std::endl; #ifndef _WIN32 if (!Config->cmdline.nofork) @@ -559,7 +559,7 @@ InspIRCd::InspIRCd(int argc, char** argv) : QueryPerformanceFrequency(&stats->QPFrequency); #endif - Logs->Log("STARTUP", LOG_DEFAULT, "Startup complete as '%s'[%s], %d max open sockets", Config->ServerName.c_str(),Config->GetSID().c_str(), SE->GetMaxFds()); + Logs->Log("STARTUP", LOG_DEFAULT, "Startup complete as '%s'[%s], %d max open sockets", Config->ServerName.c_str(),Config->GetSID().c_str(), SocketEngine::GetMaxFds()); #ifndef _WIN32 std::string SetUser = Config->ConfValue("security")->getString("runasuser"); @@ -740,8 +740,8 @@ void InspIRCd::Run() * This will cause any read or write events to be * dispatched to their handlers. */ - this->SE->DispatchTrialWrites(); - this->SE->DispatchEvents(); + SocketEngine::DispatchTrialWrites(); + SocketEngine::DispatchEvents(); /* if any users were quit, take them out */ GlobalCulls.Apply(); diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp index f27e21ad8..3610addba 100644 --- a/src/inspsocket.cpp +++ b/src/inspsocket.cpp @@ -48,7 +48,7 @@ BufferedSocket::BufferedSocket(int newfd) this->fd = newfd; this->state = I_CONNECTED; if (fd > -1) - ServerInstance->SE->AddFd(this, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE); + SocketEngine::AddFd(this, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE); } void BufferedSocket::DoConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip) @@ -107,7 +107,7 @@ BufferedSocketError BufferedSocket::BeginConnect(const irc::sockets::sockaddrs& this->state = I_CONNECTING; - if (!ServerInstance->SE->AddFd(this, FD_WANT_NO_READ | FD_WANT_SINGLE_WRITE | FD_WRITE_WILL_BLOCK)) + if (!SocketEngine::AddFd(this, FD_WANT_NO_READ | FD_WANT_SINGLE_WRITE | FD_WRITE_WILL_BLOCK)) return I_ERR_NOMOREFDS; this->Timeout = new SocketTimeout(this->GetFd(), this, timeout, ServerInstance->Time()); @@ -138,7 +138,7 @@ void StreamSocket::Close() DelIOHook(); } SocketEngine::Shutdown(this, 2); - ServerInstance->SE->DelFd(this); + SocketEngine::DelFd(this); SocketEngine::Close(this); fd = -1; } @@ -184,36 +184,36 @@ void StreamSocket::DoRead() else { char* ReadBuffer = ServerInstance->GetReadBuffer(); - int n = ServerInstance->SE->Recv(this, ReadBuffer, ServerInstance->Config->NetBufferSize, 0); + int n = SocketEngine::Recv(this, ReadBuffer, ServerInstance->Config->NetBufferSize, 0); if (n == ServerInstance->Config->NetBufferSize) { - ServerInstance->SE->ChangeEventMask(this, FD_WANT_FAST_READ | FD_ADD_TRIAL_READ); + SocketEngine::ChangeEventMask(this, FD_WANT_FAST_READ | FD_ADD_TRIAL_READ); recvq.append(ReadBuffer, n); OnDataReady(); } else if (n > 0) { - ServerInstance->SE->ChangeEventMask(this, FD_WANT_FAST_READ); + SocketEngine::ChangeEventMask(this, FD_WANT_FAST_READ); recvq.append(ReadBuffer, n); OnDataReady(); } else if (n == 0) { error = "Connection closed"; - ServerInstance->SE->ChangeEventMask(this, FD_WANT_NO_READ | FD_WANT_NO_WRITE); + SocketEngine::ChangeEventMask(this, FD_WANT_NO_READ | FD_WANT_NO_WRITE); } else if (SocketEngine::IgnoreError()) { - ServerInstance->SE->ChangeEventMask(this, FD_WANT_FAST_READ | FD_READ_WILL_BLOCK); + SocketEngine::ChangeEventMask(this, FD_WANT_FAST_READ | FD_READ_WILL_BLOCK); } else if (errno == EINTR) { - ServerInstance->SE->ChangeEventMask(this, FD_WANT_FAST_READ | FD_ADD_TRIAL_READ); + SocketEngine::ChangeEventMask(this, FD_WANT_FAST_READ | FD_ADD_TRIAL_READ); } else { error = SocketEngine::LastError(); - ServerInstance->SE->ChangeEventMask(this, FD_WANT_NO_READ | FD_WANT_NO_WRITE); + SocketEngine::ChangeEventMask(this, FD_WANT_NO_READ | FD_WANT_NO_WRITE); } } } @@ -287,7 +287,7 @@ void StreamSocket::DoWrite() #ifdef DISABLE_WRITEV else { - rv = ServerInstance->SE->Send(this, front.data(), itemlen, 0); + rv = SocketEngine::Send(this, front.data(), itemlen, 0); if (rv == 0) { SetError("Connection closed"); @@ -296,14 +296,14 @@ void StreamSocket::DoWrite() else if (rv < 0) { if (errno == EINTR || SocketEngine::IgnoreError()) - ServerInstance->SE->ChangeEventMask(this, FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK); + SocketEngine::ChangeEventMask(this, FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK); else SetError(SocketEngine::LastError()); return; } else if (rv < itemlen) { - ServerInstance->SE->ChangeEventMask(this, FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK); + SocketEngine::ChangeEventMask(this, FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK); front = front.substr(rv); sendq_len -= rv; return; @@ -313,7 +313,7 @@ void StreamSocket::DoWrite() sendq_len -= itemlen; sendq.pop_front(); if (sendq.empty()) - ServerInstance->SE->ChangeEventMask(this, FD_WANT_EDGE_WRITE); + SocketEngine::ChangeEventMask(this, FD_WANT_EDGE_WRITE); } } #endif @@ -409,11 +409,11 @@ void StreamSocket::DoWrite() if (!error.empty()) { // error - kill all events - ServerInstance->SE->ChangeEventMask(this, FD_WANT_NO_READ | FD_WANT_NO_WRITE); + SocketEngine::ChangeEventMask(this, FD_WANT_NO_READ | FD_WANT_NO_WRITE); } else { - ServerInstance->SE->ChangeEventMask(this, eventChange); + SocketEngine::ChangeEventMask(this, eventChange); } } #endif @@ -432,14 +432,14 @@ void StreamSocket::WriteData(const std::string &data) sendq.push_back(data); sendq_len += data.length(); - ServerInstance->SE->ChangeEventMask(this, FD_ADD_TRIAL_WRITE); + SocketEngine::ChangeEventMask(this, FD_ADD_TRIAL_WRITE); } bool SocketTimeout::Tick(time_t) { ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "SocketTimeout::Tick"); - if (ServerInstance->SE->GetRef(this->sfd) != this->sock) + if (SocketEngine::GetRef(this->sfd) != this->sock) { delete this; return false; @@ -473,7 +473,7 @@ void BufferedSocket::DoWrite() state = I_CONNECTED; this->OnConnected(); if (!GetIOHook()) - ServerInstance->SE->ChangeEventMask(this, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE); + SocketEngine::ChangeEventMask(this, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE); } this->StreamSocket::DoWrite(); } diff --git a/src/listensocket.cpp b/src/listensocket.cpp index 565b6b6d8..0f926aaf6 100644 --- a/src/listensocket.cpp +++ b/src/listensocket.cpp @@ -85,7 +85,7 @@ ListenSocket::ListenSocket(ConfigTag* tag, const irc::sockets::sockaddrs& bind_t else { SocketEngine::NonBlocking(this->fd); - ServerInstance->SE->AddFd(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); + SocketEngine::AddFd(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); this->ResetIOHookProvider(); } @@ -95,7 +95,7 @@ ListenSocket::~ListenSocket() { if (this->GetFd() > -1) { - ServerInstance->SE->DelFd(this); + SocketEngine::DelFd(this); ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Shut down listener on fd %d", this->fd); SocketEngine::Shutdown(this, 2); if (SocketEngine::Close(this) != 0) @@ -137,7 +137,7 @@ void ListenSocket::AcceptInternal() * which for the time being is a physical impossibility (even the largest networks dont have more * than about 10,000 users on ONE server!) */ - if (incomingSockfd >= ServerInstance->SE->GetMaxFds()) + if (incomingSockfd >= SocketEngine::GetMaxFds()) { ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Server is full"); SocketEngine::Shutdown(incomingSockfd, 2); diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp index b3b7d43df..9a8e63e57 100644 --- a/src/modules/extra/m_pgsql.cpp +++ b/src/modules/extra/m_pgsql.cpp @@ -241,7 +241,7 @@ class SQLConn : public SQLProvider, public EventHandler if(this->fd <= -1) return false; - if (!ServerInstance->SE->AddFd(this, FD_WANT_NO_WRITE | FD_WANT_NO_READ)) + if (!SocketEngine::AddFd(this, FD_WANT_NO_WRITE | FD_WANT_NO_READ)) { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "BUG: Couldn't add pgsql socket to socket engine"); return false; @@ -256,17 +256,17 @@ class SQLConn : public SQLProvider, public EventHandler switch(PQconnectPoll(sql)) { case PGRES_POLLING_WRITING: - ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_WRITE | FD_WANT_NO_READ); + SocketEngine::ChangeEventMask(this, FD_WANT_POLL_WRITE | FD_WANT_NO_READ); status = CWRITE; return true; case PGRES_POLLING_READING: - ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); + SocketEngine::ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); status = CREAD; return true; case PGRES_POLLING_FAILED: return false; case PGRES_POLLING_OK: - ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); + SocketEngine::ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); status = WWRITE; DoConnectedPoll(); default: @@ -349,17 +349,17 @@ restart: switch(PQresetPoll(sql)) { case PGRES_POLLING_WRITING: - ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_WRITE | FD_WANT_NO_READ); + SocketEngine::ChangeEventMask(this, FD_WANT_POLL_WRITE | FD_WANT_NO_READ); status = CWRITE; return DoPoll(); case PGRES_POLLING_READING: - ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); + SocketEngine::ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); status = CREAD; return true; case PGRES_POLLING_FAILED: return false; case PGRES_POLLING_OK: - ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); + SocketEngine::ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); status = WWRITE; DoConnectedPoll(); default: @@ -487,7 +487,7 @@ restart: void Close() { - ServerInstance->SE->DelFd(this); + SocketEngine::DelFd(this); if(sql) { diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 50ad4af81..53ed59816 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -588,13 +588,13 @@ class GnuTLSIOHook : public SSLIOHook { // gnutls_handshake() wants to read() again. this->status = ISSL_HANDSHAKING_READ; - ServerInstance->SE->ChangeEventMask(user, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); } else { // gnutls_handshake() wants to write() again. this->status = ISSL_HANDSHAKING_WRITE; - ServerInstance->SE->ChangeEventMask(user, FD_WANT_NO_READ | FD_WANT_SINGLE_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_NO_READ | FD_WANT_SINGLE_WRITE); } } else @@ -614,7 +614,7 @@ class GnuTLSIOHook : public SSLIOHook VerifyCertificate(); // Finish writing, if any left - ServerInstance->SE->ChangeEventMask(user, FD_WANT_POLL_READ | FD_WANT_NO_WRITE | FD_ADD_TRIAL_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_POLL_READ | FD_WANT_NO_WRITE | FD_ADD_TRIAL_WRITE); return true; } @@ -734,7 +734,7 @@ info_done_dealloc: return -1; } - int rv = ServerInstance->SE->Recv(sock, reinterpret_cast<char *>(buffer), size, 0); + int rv = SocketEngine::Recv(sock, reinterpret_cast<char *>(buffer), size, 0); #ifdef _WIN32 if (rv < 0) @@ -749,7 +749,7 @@ info_done_dealloc: #endif if (rv < (int)size) - ServerInstance->SE->ChangeEventMask(sock, FD_READ_WILL_BLOCK); + SocketEngine::ChangeEventMask(sock, FD_READ_WILL_BLOCK); return rv; } @@ -770,7 +770,7 @@ info_done_dealloc: return -1; } - int rv = ServerInstance->SE->Send(sock, reinterpret_cast<const char *>(buffer), size, 0); + int rv = SocketEngine::Send(sock, reinterpret_cast<const char *>(buffer), size, 0); #ifdef _WIN32 if (rv < 0) @@ -785,7 +785,7 @@ info_done_dealloc: #endif if (rv < (int)size) - ServerInstance->SE->ChangeEventMask(sock, FD_WRITE_WILL_BLOCK); + SocketEngine::ChangeEventMask(sock, FD_WRITE_WILL_BLOCK); return rv; } @@ -888,18 +888,18 @@ info_done_dealloc: if (ret == (int)sendq.length()) { - ServerInstance->SE->ChangeEventMask(user, FD_WANT_NO_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_NO_WRITE); return 1; } else if (ret > 0) { sendq = sendq.substr(ret); - ServerInstance->SE->ChangeEventMask(user, FD_WANT_SINGLE_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_SINGLE_WRITE); return 0; } else if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED || ret == 0) { - ServerInstance->SE->ChangeEventMask(user, FD_WANT_SINGLE_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_SINGLE_WRITE); return 0; } else // (ret < 0) diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 962350e1c..53a01724b 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -273,13 +273,13 @@ class OpenSSLIOHook : public SSLIOHook if (err == SSL_ERROR_WANT_READ) { - ServerInstance->SE->ChangeEventMask(user, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); this->status = ISSL_HANDSHAKING; return true; } else if (err == SSL_ERROR_WANT_WRITE) { - ServerInstance->SE->ChangeEventMask(user, FD_WANT_NO_READ | FD_WANT_SINGLE_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_NO_READ | FD_WANT_SINGLE_WRITE); this->status = ISSL_HANDSHAKING; return true; } @@ -297,7 +297,7 @@ class OpenSSLIOHook : public SSLIOHook status = ISSL_OPEN; - ServerInstance->SE->ChangeEventMask(user, FD_WANT_POLL_READ | FD_WANT_NO_WRITE | FD_ADD_TRIAL_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_POLL_READ | FD_WANT_NO_WRITE | FD_ADD_TRIAL_WRITE); return true; } @@ -427,7 +427,7 @@ class OpenSSLIOHook : public SSLIOHook { recvq.append(buffer, ret); if (data_to_write) - ServerInstance->SE->ChangeEventMask(user, FD_WANT_POLL_READ | FD_WANT_SINGLE_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_POLL_READ | FD_WANT_SINGLE_WRITE); return 1; } else if (ret == 0) @@ -443,12 +443,12 @@ class OpenSSLIOHook : public SSLIOHook if (err == SSL_ERROR_WANT_READ) { - ServerInstance->SE->ChangeEventMask(user, FD_WANT_POLL_READ); + SocketEngine::ChangeEventMask(user, FD_WANT_POLL_READ); return 0; } else if (err == SSL_ERROR_WANT_WRITE) { - ServerInstance->SE->ChangeEventMask(user, FD_WANT_NO_READ | FD_WANT_SINGLE_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_NO_READ | FD_WANT_SINGLE_WRITE); return 0; } else @@ -489,13 +489,13 @@ class OpenSSLIOHook : public SSLIOHook if (ret == (int)buffer.length()) { data_to_write = false; - ServerInstance->SE->ChangeEventMask(user, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); return 1; } else if (ret > 0) { buffer = buffer.substr(ret); - ServerInstance->SE->ChangeEventMask(user, FD_WANT_SINGLE_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_SINGLE_WRITE); return 0; } else if (ret == 0) @@ -509,12 +509,12 @@ class OpenSSLIOHook : public SSLIOHook if (err == SSL_ERROR_WANT_WRITE) { - ServerInstance->SE->ChangeEventMask(user, FD_WANT_SINGLE_WRITE); + SocketEngine::ChangeEventMask(user, FD_WANT_SINGLE_WRITE); return 0; } else if (err == SSL_ERROR_WANT_READ) { - ServerInstance->SE->ChangeEventMask(user, FD_WANT_POLL_READ); + SocketEngine::ChangeEventMask(user, FD_WANT_POLL_READ); return 0; } else diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp index e94ee2504..065ba0bce 100644 --- a/src/modules/m_httpd_stats.cpp +++ b/src/modules/m_httpd_stats.cpp @@ -107,7 +107,7 @@ class ModuleHttpStats : public Module data << "<usercount>" << ServerInstance->Users->clientlist->size() << "</usercount>"; data << "<channelcount>" << ServerInstance->chanlist->size() << "</channelcount>"; data << "<opercount>" << ServerInstance->Users->all_opers.size() << "</opercount>"; - data << "<socketcount>" << (ServerInstance->SE->GetUsedFds()) << "</socketcount><socketmax>" << ServerInstance->SE->GetMaxFds() << "</socketmax><socketengine>" INSPIRCD_SOCKETENGINE_NAME "</socketengine>"; + data << "<socketcount>" << (SocketEngine::GetUsedFds()) << "</socketcount><socketmax>" << SocketEngine::GetMaxFds() << "</socketmax><socketengine>" INSPIRCD_SOCKETENGINE_NAME "</socketengine>"; time_t current_time = 0; current_time = ServerInstance->Time(); diff --git a/src/modules/m_ident.cpp b/src/modules/m_ident.cpp index 1f36c84fb..bea4c2803 100644 --- a/src/modules/m_ident.cpp +++ b/src/modules/m_ident.cpp @@ -133,7 +133,7 @@ class IdentRequestSocket : public EventHandler } /* Add fd to socket engine */ - if (!ServerInstance->SE->AddFd(this, FD_WANT_NO_READ | FD_WANT_POLL_WRITE)) + if (!SocketEngine::AddFd(this, FD_WANT_NO_READ | FD_WANT_POLL_WRITE)) { this->Close(); throw ModuleException("out of fds"); @@ -143,7 +143,7 @@ class IdentRequestSocket : public EventHandler void OnConnected() { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "OnConnected()"); - ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); + SocketEngine::ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE); char req[32]; @@ -159,7 +159,7 @@ class IdentRequestSocket : public EventHandler /* Send failed if we didnt write the whole ident request -- * might as well give up if this happens! */ - if (ServerInstance->SE->Send(this, req, req_size, 0) < req_size) + if (SocketEngine::Send(this, req, req_size, 0) < req_size) done = true; } @@ -195,7 +195,7 @@ class IdentRequestSocket : public EventHandler if (GetFd() > -1) { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Close ident socket %d", GetFd()); - ServerInstance->SE->DelFd(this); + SocketEngine::DelFd(this); SocketEngine::Close(GetFd()); this->SetFd(-1); } @@ -212,7 +212,7 @@ class IdentRequestSocket : public EventHandler * extremely short - there is *no* sane reason it'd be in more than one packet */ char ibuf[256]; - int recvresult = ServerInstance->SE->Recv(this, ibuf, sizeof(ibuf)-1, 0); + int recvresult = SocketEngine::Recv(this, ibuf, sizeof(ibuf)-1, 0); /* Close (but don't delete from memory) our socket * and flag as done since the ident lookup has finished diff --git a/src/modules/m_spanningtree/override_squit.cpp b/src/modules/m_spanningtree/override_squit.cpp index 1d0781dc3..2bae80927 100644 --- a/src/modules/m_spanningtree/override_squit.cpp +++ b/src/modules/m_spanningtree/override_squit.cpp @@ -42,7 +42,7 @@ ModResult ModuleSpanningTree::HandleSquit(const std::vector<std::string>& parame { ServerInstance->SNO->WriteToSnoMask('l',"SQUIT: Server \002%s\002 removed from network by %s",parameters[0].c_str(),user->nick.c_str()); sock->Squit(s,"Server quit by " + user->GetFullRealHost()); - ServerInstance->SE->DelFd(sock); + SocketEngine::DelFd(sock); sock->Close(); } else diff --git a/src/socketengine.cpp b/src/socketengine.cpp index ba3d84512..698b9061f 100644 --- a/src/socketengine.cpp +++ b/src/socketengine.cpp @@ -23,6 +23,25 @@ #include "inspircd.h" + +/** Reference table, contains all current handlers + **/ +std::vector<EventHandler*> SocketEngine::ref; + +/** Current number of descriptors in the engine + */ +size_t SocketEngine::CurrentSetSize = 0; + +/** List of handlers that want a trial read/write + */ +std::set<int> SocketEngine::trials; + +int SocketEngine::MAX_DESCRIPTORS; + +/** Socket engine statistics: count of various events, bandwidth usage + */ +SocketEngine::Statistics SocketEngine::stats; + EventHandler::EventHandler() { fd = -1; @@ -34,20 +53,6 @@ void EventHandler::SetFd(int FD) this->fd = FD; } -SocketEngine::SocketEngine() -{ - CurrentSetSize = 0; -} - -SocketEngine::~SocketEngine() -{ -} - -void SocketEngine::SetEventMask(EventHandler* eh, int mask) -{ - eh->event_mask = mask; -} - void SocketEngine::ChangeEventMask(EventHandler* eh, int change) { int old_m = eh->event_mask; @@ -250,10 +255,6 @@ int SocketEngine::Shutdown(int fd, int how) return shutdown(fd, how); } -void SocketEngine::RecoverFromFork() -{ -} - void SocketEngine::Statistics::Update(size_t len_in, size_t len_out) { CheckFlush(); diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp index 39cc60606..961dc8b49 100644 --- a/src/socketengines/socketengine_epoll.cpp +++ b/src/socketengines/socketengine_epoll.cpp @@ -31,27 +31,16 @@ /** A specialisation of the SocketEngine class, designed to use linux 2.6 epoll(). */ -class EPollEngine : public SocketEngine +namespace { -private: - /** These are used by epoll() to hold socket events - */ - std::vector<struct epoll_event> events; int EngineHandle; -public: - /** Create a new EPollEngine - */ - EPollEngine(); - /** Delete an EPollEngine + + /** These are used by epoll() to hold socket events */ - virtual ~EPollEngine(); - virtual bool AddFd(EventHandler* eh, int event_mask); - virtual void OnSetEvent(EventHandler* eh, int old_mask, int new_mask); - virtual void DelFd(EventHandler* eh); - virtual int DispatchEvents(); -}; + std::vector<struct epoll_event> events(1); +} -EPollEngine::EPollEngine() : events(1) +void SocketEngine::Init() { int max = ulimit(4, 0); if (max > 0) @@ -78,9 +67,13 @@ EPollEngine::EPollEngine() : events(1) } } -EPollEngine::~EPollEngine() +void SocketEngine::RecoverFromFork() { - this->Close(EngineHandle); +} + +void SocketEngine::Deinit() +{ + Close(EngineHandle); } static unsigned mask_to_epoll(int event_mask) @@ -106,7 +99,7 @@ static unsigned mask_to_epoll(int event_mask) return rv; } -bool EPollEngine::AddFd(EventHandler* eh, int event_mask) +bool SocketEngine::AddFd(EventHandler* eh, int event_mask) { int fd = eh->GetFd(); if ((fd < 0) || (fd > GetMaxFds() - 1)) @@ -134,13 +127,13 @@ bool EPollEngine::AddFd(EventHandler* eh, int event_mask) ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "New file descriptor: %d", fd); - SocketEngine::SetEventMask(eh, event_mask); + eh->SetEventMask(event_mask); ResizeDouble(events); return true; } -void EPollEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) +void SocketEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) { unsigned old_events = mask_to_epoll(old_mask); unsigned new_events = mask_to_epoll(new_mask); @@ -155,7 +148,7 @@ void EPollEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) } } -void EPollEngine::DelFd(EventHandler* eh) +void SocketEngine::DelFd(EventHandler* eh) { int fd = eh->GetFd(); if ((fd < 0) || (fd > GetMaxFds() - 1)) @@ -180,7 +173,7 @@ void EPollEngine::DelFd(EventHandler* eh) ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Remove file descriptor: %d", fd); } -int EPollEngine::DispatchEvents() +int SocketEngine::DispatchEvents() { int i = epoll_wait(EngineHandle, &events[0], events.size(), 1000); ServerInstance->UpdateTime(); @@ -232,7 +225,7 @@ int EPollEngine::DispatchEvents() mask = nm; } } - SetEventMask(eh, mask); + eh->SetEventMask(mask); if (ev.events & EPOLLIN) { stats.ReadEvents++; @@ -250,8 +243,3 @@ int EPollEngine::DispatchEvents() return i; } - -SocketEngine* CreateSocketEngine() -{ - return new EPollEngine; -} diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp index 0a9a0a399..61f5cd922 100644 --- a/src/socketengines/socketengine_kqueue.cpp +++ b/src/socketengines/socketengine_kqueue.cpp @@ -30,28 +30,17 @@ /** A specialisation of the SocketEngine class, designed to use BSD kqueue(). */ -class KQueueEngine : public SocketEngine +namespace { -private: int EngineHandle; /** These are used by kqueue() to hold socket events */ - std::vector<struct kevent> ke_list; -public: - /** Create a new KQueueEngine - */ - KQueueEngine(); - /** Delete a KQueueEngine - */ - virtual ~KQueueEngine(); - bool AddFd(EventHandler* eh, int event_mask); - void OnSetEvent(EventHandler* eh, int old_mask, int new_mask); - virtual void DelFd(EventHandler* eh); - virtual int DispatchEvents(); - virtual void RecoverFromFork(); -}; - -KQueueEngine::KQueueEngine() : ke_list(1) + std::vector<struct kevent> ke_list(16); +} + +/** Initialize the kqueue engine + */ +void SocketEngine::Init() { MAX_DESCRIPTORS = 0; int mib[2]; @@ -72,10 +61,10 @@ KQueueEngine::KQueueEngine() : ke_list(1) ServerInstance->QuickExit(EXIT_STATUS_SOCKETENGINE); } - this->RecoverFromFork(); + RecoverFromFork(); } -void KQueueEngine::RecoverFromFork() +void SocketEngine::RecoverFromFork() { /* * The only bad thing about kqueue is that its fd cant survive a fork and is not inherited. @@ -93,12 +82,14 @@ void KQueueEngine::RecoverFromFork() } } -KQueueEngine::~KQueueEngine() +/** Shutdown the kqueue engine + */ +void SocketEngine::Deinit() { - this->Close(EngineHandle); + Close(EngineHandle); } -bool KQueueEngine::AddFd(EventHandler* eh, int event_mask) +bool SocketEngine::AddFd(EventHandler* eh, int event_mask) { int fd = eh->GetFd(); @@ -122,14 +113,14 @@ bool KQueueEngine::AddFd(EventHandler* eh, int event_mask) ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "New file descriptor: %d", fd); - SocketEngine::SetEventMask(eh, event_mask); + eh->SetEventMask(event_mask); OnSetEvent(eh, 0, event_mask); ResizeDouble(ke_list); return true; } -void KQueueEngine::DelFd(EventHandler* eh) +void SocketEngine::DelFd(EventHandler* eh) { int fd = eh->GetFd(); @@ -161,7 +152,7 @@ void KQueueEngine::DelFd(EventHandler* eh) ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Remove file descriptor: %d", fd); } -void KQueueEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) +void SocketEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) { if ((new_mask & FD_WANT_POLL_WRITE) && !(old_mask & FD_WANT_POLL_WRITE)) { @@ -195,7 +186,7 @@ void KQueueEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) } } -int KQueueEngine::DispatchEvents() +int SocketEngine::DispatchEvents() { struct timespec ts; ts.tv_nsec = 0; @@ -235,21 +226,16 @@ int KQueueEngine::DispatchEvents() * to detect when it set again. */ const int bits_to_clr = FD_WANT_SINGLE_WRITE | FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK; - SetEventMask(eh, eh->GetEventMask() & ~bits_to_clr); + eh->SetEventMask(eh->GetEventMask() & ~bits_to_clr); eh->HandleEvent(EVENT_WRITE); } else if (filter == EVFILT_READ) { stats.ReadEvents++; - SetEventMask(eh, eh->GetEventMask() & ~FD_READ_WILL_BLOCK); + eh->SetEventMask(eh->GetEventMask() & ~FD_READ_WILL_BLOCK); eh->HandleEvent(EVENT_READ); } } return i; } - -SocketEngine* CreateSocketEngine() -{ - return new KQueueEngine; -} diff --git a/src/socketengines/socketengine_poll.cpp b/src/socketengines/socketengine_poll.cpp index 46a517c51..ac5e02cfd 100644 --- a/src/socketengines/socketengine_poll.cpp +++ b/src/socketengines/socketengine_poll.cpp @@ -43,26 +43,17 @@ /** A specialisation of the SocketEngine class, designed to use poll(). */ -class PollEngine : public SocketEngine +namespace { -private: /** These are used by poll() to hold socket events */ - std::vector<struct pollfd> events; + std::vector<struct pollfd> events(16); /** This vector maps fds to an index in the events array. */ - std::vector<int> fd_mappings; -public: - /** Create a new PollEngine - */ - PollEngine(); - virtual bool AddFd(EventHandler* eh, int event_mask); - virtual void OnSetEvent(EventHandler* eh, int old_mask, int new_mask); - virtual void DelFd(EventHandler* eh); - virtual int DispatchEvents(); -}; - -PollEngine::PollEngine() : events(1), fd_mappings(1) + std::vector<int> fd_mappings(16); +} + +void SocketEngine::Init() { struct rlimit limits; if (!getrlimit(RLIMIT_NOFILE, &limits)) @@ -77,6 +68,14 @@ PollEngine::PollEngine() : events(1), fd_mappings(1) } } +void SocketEngine::Deinit() +{ +} + +void SocketEngine::RecoverFromFork() +{ +} + static int mask_to_poll(int event_mask) { int rv = 0; @@ -87,7 +86,7 @@ static int mask_to_poll(int event_mask) return rv; } -bool PollEngine::AddFd(EventHandler* eh, int event_mask) +bool SocketEngine::AddFd(EventHandler* eh, int event_mask) { int fd = eh->GetFd(); if ((fd < 0) || (fd > GetMaxFds() - 1)) @@ -119,11 +118,11 @@ bool PollEngine::AddFd(EventHandler* eh, int event_mask) events[index].events = mask_to_poll(event_mask); ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "New file descriptor: %d (%d; index %d)", fd, events[index].events, index); - SocketEngine::SetEventMask(eh, event_mask); + eh->SetEventMask(event_mask); return true; } -void PollEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) +void SocketEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) { int fd = eh->GetFd(); if (fd < 0 || static_cast<unsigned int>(fd) >= fd_mappings.size() || fd_mappings[fd] == -1) @@ -135,7 +134,7 @@ void PollEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) events[fd_mappings[fd]].events = mask_to_poll(new_mask); } -void PollEngine::DelFd(EventHandler* eh) +void SocketEngine::DelFd(EventHandler* eh) { int fd = eh->GetFd(); if ((fd < 0) || (fd > MAX_DESCRIPTORS)) @@ -178,7 +177,7 @@ void PollEngine::DelFd(EventHandler* eh) "(Filled gap with: %d (index: %d))", fd, index, last_fd, last_index); } -int PollEngine::DispatchEvents() +int SocketEngine::DispatchEvents() { int i = poll(&events[0], CurrentSetSize, 1000); int processed = 0; @@ -218,7 +217,7 @@ int PollEngine::DispatchEvents() if (revents & POLLIN) { - SetEventMask(eh, eh->GetEventMask() & ~FD_READ_WILL_BLOCK); + eh->SetEventMask(eh->GetEventMask() & ~FD_READ_WILL_BLOCK); eh->HandleEvent(EVENT_READ); if (eh != GetRef(fd)) // whoops, deleted out from under us @@ -229,7 +228,7 @@ int PollEngine::DispatchEvents() { int mask = eh->GetEventMask(); mask &= ~(FD_WRITE_WILL_BLOCK | FD_WANT_SINGLE_WRITE); - SetEventMask(eh, mask); + eh->SetEventMask(mask); // The vector could've been resized, reference can be invalid by now; don't use it events[index].events = mask_to_poll(mask); @@ -239,8 +238,3 @@ int PollEngine::DispatchEvents() return i; } - -SocketEngine* CreateSocketEngine() -{ - return new PollEngine; -} diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp index e1fcc0e6c..d7425813e 100644 --- a/src/socketengines/socketengine_ports.cpp +++ b/src/socketengines/socketengine_ports.cpp @@ -36,27 +36,17 @@ /** A specialisation of the SocketEngine class, designed to use solaris 10 I/O completion ports */ -class PortsEngine : public SocketEngine +namespace { -private: /** These are used by ports to hold socket events */ - std::vector<port_event_t> events; + std::vector<port_event_t> events(16); int EngineHandle; -public: - /** Create a new PortsEngine - */ - PortsEngine(); - /** Delete a PortsEngine - */ - virtual ~PortsEngine(); - virtual bool AddFd(EventHandler* eh, int event_mask); - virtual void OnSetEvent(EventHandler* eh, int old_mask, int new_mask); - virtual void DelFd(EventHandler* eh); - virtual int DispatchEvents(); -}; - -PortsEngine::PortsEngine() : events(1) +} + +/** Initialize ports engine + */ +void SocketEngine::Init() { int max = ulimit(4, 0); if (max > 0) @@ -81,9 +71,15 @@ PortsEngine::PortsEngine() : events(1) } } -PortsEngine::~PortsEngine() +/** Shutdown the ports engine + */ +void SocketEngine::Deinit() +{ + SocketEngine::Close(EngineHandle); +} + +void SocketEngine::RecoverFromFork() { - this->Close(EngineHandle); } static int mask_to_events(int event_mask) @@ -96,7 +92,7 @@ static int mask_to_events(int event_mask) return rv; } -bool PortsEngine::AddFd(EventHandler* eh, int event_mask) +bool SocketEngine::AddFd(EventHandler* eh, int event_mask) { int fd = eh->GetFd(); if ((fd < 0) || (fd > GetMaxFds() - 1)) @@ -105,7 +101,7 @@ bool PortsEngine::AddFd(EventHandler* eh, int event_mask) if (!SocketEngine::AddFdRef(eh)) return false; - SocketEngine::SetEventMask(eh, event_mask); + eh->SetEventMask(event_mask); port_associate(EngineHandle, PORT_SOURCE_FD, fd, mask_to_events(event_mask), eh); ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "New file descriptor: %d", fd); @@ -114,13 +110,13 @@ bool PortsEngine::AddFd(EventHandler* eh, int event_mask) return true; } -void PortsEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) +void SocketEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) { if (mask_to_events(new_mask) != mask_to_events(old_mask)) port_associate(EngineHandle, PORT_SOURCE_FD, eh->GetFd(), mask_to_events(new_mask), eh); } -void PortsEngine::DelFd(EventHandler* eh) +void SocketEngine::DelFd(EventHandler* eh) { int fd = eh->GetFd(); if ((fd < 0) || (fd > GetMaxFds() - 1)) @@ -133,7 +129,7 @@ void PortsEngine::DelFd(EventHandler* eh) ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Remove file descriptor: %d", fd); } -int PortsEngine::DispatchEvents() +int SocketEngine::DispatchEvents() { struct timespec poll_time; @@ -171,7 +167,7 @@ int PortsEngine::DispatchEvents() if (portev_events & POLLRDNORM) mask &= ~FD_READ_WILL_BLOCK; // reinsert port for next time around, pretending to be one-shot for writes - SetEventMask(eh, mask); + eh->SetEventMask(mask); port_associate(EngineHandle, PORT_SOURCE_FD, fd, mask_to_events(mask), eh); if (portev_events & POLLRDNORM) { @@ -189,8 +185,3 @@ int PortsEngine::DispatchEvents() return (int)i; } - -SocketEngine* CreateSocketEngine() -{ - return new PortsEngine; -} diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp index be380cb46..79f1b3635 100644 --- a/src/socketengines/socketengine_select.cpp +++ b/src/socketengines/socketengine_select.cpp @@ -28,32 +28,30 @@ /** A specialisation of the SocketEngine class, designed to use traditional select(). */ -class SelectEngine : public SocketEngine +namespace { fd_set ReadSet, WriteSet, ErrSet; - int MaxFD; - -public: - /** Create a new SelectEngine - */ - SelectEngine(); - virtual bool AddFd(EventHandler* eh, int event_mask); - virtual void DelFd(EventHandler* eh); - void OnSetEvent(EventHandler* eh, int, int); - virtual int DispatchEvents(); -}; - -SelectEngine::SelectEngine() + int MaxFD = 0; +} + +void SocketEngine::Init() { MAX_DESCRIPTORS = FD_SETSIZE; FD_ZERO(&ReadSet); FD_ZERO(&WriteSet); FD_ZERO(&ErrSet); - MaxFD = 0; } -bool SelectEngine::AddFd(EventHandler* eh, int event_mask) +void SocketEngine::Deinit() +{ +} + +void SocketEngine::RecoverFromFork() +{ +} + +bool SocketEngine::AddFd(EventHandler* eh, int event_mask) { int fd = eh->GetFd(); if ((fd < 0) || (fd > GetMaxFds() - 1)) @@ -62,7 +60,7 @@ bool SelectEngine::AddFd(EventHandler* eh, int event_mask) if (!SocketEngine::AddFdRef(eh)) return false; - SocketEngine::SetEventMask(eh, event_mask); + eh->SetEventMask(event_mask); OnSetEvent(eh, 0, event_mask); FD_SET(fd, &ErrSet); if (fd > MaxFD) @@ -72,7 +70,7 @@ bool SelectEngine::AddFd(EventHandler* eh, int event_mask) return true; } -void SelectEngine::DelFd(EventHandler* eh) +void SocketEngine::DelFd(EventHandler* eh) { int fd = eh->GetFd(); @@ -90,7 +88,7 @@ void SelectEngine::DelFd(EventHandler* eh) ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Remove file descriptor: %d", fd); } -void SelectEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) +void SocketEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) { int fd = eh->GetFd(); int diff = old_mask ^ new_mask; @@ -111,7 +109,7 @@ void SelectEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) } } -int SelectEngine::DispatchEvents() +int SocketEngine::DispatchEvents() { static timeval tval = { 1, 0 }; @@ -149,7 +147,7 @@ int SelectEngine::DispatchEvents() if (has_read) { stats.ReadEvents++; - SetEventMask(ev, ev->GetEventMask() & ~FD_READ_WILL_BLOCK); + ev->SetEventMask(ev->GetEventMask() & ~FD_READ_WILL_BLOCK); ev->HandleEvent(EVENT_READ); if (ev != GetRef(i)) continue; @@ -159,16 +157,11 @@ int SelectEngine::DispatchEvents() { stats.WriteEvents++; int newmask = (ev->GetEventMask() & ~(FD_WRITE_WILL_BLOCK | FD_WANT_SINGLE_WRITE)); - this->OnSetEvent(ev, ev->GetEventMask(), newmask); - SetEventMask(ev, newmask); + SocketEngine::OnSetEvent(ev, ev->GetEventMask(), newmask); + ev->SetEventMask(newmask); ev->HandleEvent(EVENT_WRITE); } } return sresult; } - -SocketEngine* CreateSocketEngine() -{ - return new SelectEngine; -} diff --git a/src/threadengines/threadengine_pthread.cpp b/src/threadengines/threadengine_pthread.cpp index ebd11d487..27641f0ac 100644 --- a/src/threadengines/threadengine_pthread.cpp +++ b/src/threadengines/threadengine_pthread.cpp @@ -75,12 +75,12 @@ class ThreadSignalSocket : public EventHandler ThreadSignalSocket(SocketThread* p, int newfd) : parent(p) { SetFd(newfd); - ServerInstance->SE->AddFd(this, FD_WANT_FAST_READ | FD_WANT_NO_WRITE); + SocketEngine::AddFd(this, FD_WANT_FAST_READ | FD_WANT_NO_WRITE); } ~ThreadSignalSocket() { - ServerInstance->SE->DelFd(this); + SocketEngine::DelFd(this); SocketEngine::Close(GetFd()); } @@ -124,13 +124,13 @@ class ThreadSignalSocket : public EventHandler { SetFd(recvfd); SocketEngine::NonBlocking(fd); - ServerInstance->SE->AddFd(this, FD_WANT_FAST_READ | FD_WANT_NO_WRITE); + SocketEngine::AddFd(this, FD_WANT_FAST_READ | FD_WANT_NO_WRITE); } ~ThreadSignalSocket() { close(send_fd); - ServerInstance->SE->DelFd(this); + SocketEngine::DelFd(this); SocketEngine::Close(GetFd()); } diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 5d428a15f..12db0dde2 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -83,7 +83,7 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs this->local_users.push_front(New); - if ((this->local_users.size() > ServerInstance->Config->SoftLimit) || (this->local_users.size() >= (unsigned int)ServerInstance->SE->GetMaxFds())) + if ((this->local_users.size() > ServerInstance->Config->SoftLimit) || (this->local_users.size() >= (unsigned int)SocketEngine::GetMaxFds())) { ServerInstance->SNO->WriteToSnoMask('a', "Warning: softlimit value has been reached: %d clients", ServerInstance->Config->SoftLimit); this->QuitUser(New,"No more connections allowed"); @@ -141,7 +141,7 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs } } - if (!ServerInstance->SE->AddFd(eh, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE)) + if (!SocketEngine::AddFd(eh, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE)) { ServerInstance->Logs->Log("USERS", LOG_DEBUG, "Internal error on new connection"); this->QuitUser(New, "Internal error handling connection"); diff --git a/src/users.cpp b/src/users.cpp index 04d2114dc..eb91a9cb5 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -818,7 +818,7 @@ void User::Write(const char *text, ...) void LocalUser::Write(const std::string& text) { - if (!ServerInstance->SE->BoundsCheckFd(&eh)) + if (!SocketEngine::BoundsCheckFd(&eh)) return; if (text.length() > ServerInstance->Config->Limits.MaxLine - 2) |