summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/inspircd.h4
-rw-r--r--include/socketengine.h64
-rw-r--r--src/commands/cmd_dns.cpp8
-rw-r--r--src/commands/cmd_stats.cpp6
-rw-r--r--src/configreader.cpp4
-rw-r--r--src/inspircd.cpp14
-rw-r--r--src/inspsocket.cpp38
-rw-r--r--src/listensocket.cpp6
-rw-r--r--src/modules/extra/m_pgsql.cpp16
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp20
-rw-r--r--src/modules/extra/m_ssl_openssl.cpp20
-rw-r--r--src/modules/m_httpd_stats.cpp2
-rw-r--r--src/modules/m_ident.cpp10
-rw-r--r--src/modules/m_spanningtree/override_squit.cpp2
-rw-r--r--src/socketengine.cpp37
-rw-r--r--src/socketengines/socketengine_epoll.cpp48
-rw-r--r--src/socketengines/socketengine_kqueue.cpp54
-rw-r--r--src/socketengines/socketengine_poll.cpp48
-rw-r--r--src/socketengines/socketengine_ports.cpp51
-rw-r--r--src/socketengines/socketengine_select.cpp49
-rw-r--r--src/threadengines/threadengine_pthread.cpp8
-rw-r--r--src/usermanager.cpp4
-rw-r--r--src/users.cpp2
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)