summaryrefslogtreecommitdiff
path: root/src/core/m_socketengine_select.cpp
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2010-07-08 22:19:13 -0400
committerAdam <Adam@anope.org>2010-07-08 22:19:13 -0400
commit1cf4ebb231f2f7770b717a5e176d7bb5cbc66284 (patch)
tree16094a36484e2764c5f541c4324e1d2a6300f61b /src/core/m_socketengine_select.cpp
parent8f8b1e46d670f45bafdc5c888bec3f005cc06c1f (diff)
Added an epoll socket engine
Diffstat (limited to 'src/core/m_socketengine_select.cpp')
-rw-r--r--src/core/m_socketengine_select.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/core/m_socketengine_select.cpp b/src/core/m_socketengine_select.cpp
new file mode 100644
index 000000000..c7346f87c
--- /dev/null
+++ b/src/core/m_socketengine_select.cpp
@@ -0,0 +1,134 @@
+#include "module.h"
+
+class SocketEngineSelect : public SocketEngineBase
+{
+ private:
+ /* Max Read FD */
+ int MaxFD;
+ /* Read FDs */
+ fd_set ReadFDs;
+ /* Write FDs */
+ fd_set WriteFDs;
+
+ public:
+ SocketEngineSelect()
+ {
+ MaxFD = 0;
+ FD_ZERO(&ReadFDs);
+ FD_ZERO(&WriteFDs);
+ }
+
+ ~SocketEngineSelect()
+ {
+ FD_ZERO(&ReadFDs);
+ FD_ZERO(&WriteFDs);
+ }
+
+ void AddSocket(Socket *s)
+ {
+ if (s->GetSock() > MaxFD)
+ MaxFD = s->GetSock();
+ FD_SET(s->GetSock(), &ReadFDs);
+ Sockets.insert(std::make_pair(s->GetSock(), s));
+ }
+
+ void DelSocket(Socket *s)
+ {
+ if (s->GetSock() == MaxFD)
+ --MaxFD;
+ FD_CLR(s->GetSock(), &ReadFDs);
+ FD_CLR(s->GetSock(), &WriteFDs);
+ Sockets.erase(s->GetSock());
+ }
+
+ void MarkWriteable(Socket *s)
+ {
+ FD_SET(s->GetSock(), &WriteFDs);
+ }
+
+ void ClearWriteable(Socket *s)
+ {
+ FD_CLR(s->GetSock(), &WriteFDs);
+ }
+
+ void Process()
+ {
+ fd_set rfdset = ReadFDs, wfdset = WriteFDs, efdset = ReadFDs;
+ timeval tval;
+ tval.tv_sec = Config.ReadTimeout;
+ tval.tv_usec = 0;
+
+ int sresult = select(MaxFD + 1, &rfdset, &wfdset, &efdset, &tval);
+
+ if (sresult == -1)
+ {
+#ifdef WIN32
+ errno = WSAGetLastError();
+#endif
+ Alog() << "SockEngine::Process(): error" << strerror(errno);
+ }
+ else if (sresult)
+ {
+ for (std::map<int, Socket *>::const_iterator it = Sockets.begin(), it_end = Sockets.end(); it != it_end; ++it)
+ {
+ Socket *s = it->second;
+
+ if (FD_ISSET(s->GetSock(), &efdset))
+ {
+ s->ProcessError();
+ s->SetFlag(SF_DEAD);
+ continue;
+ }
+ if (FD_ISSET(s->GetSock(), &rfdset))
+ {
+ if (!s->ProcessRead())
+ {
+ s->SetFlag(SF_DEAD);
+ }
+ }
+ if (FD_ISSET(s->GetSock(), &wfdset))
+ {
+ if (!s->ProcessWrite())
+ {
+ s->SetFlag(SF_DEAD);
+ }
+ }
+ }
+
+ for (std::map<int, Socket *>::iterator it = Sockets.begin(), it_end = Sockets.end(); it != it_end;)
+ {
+ Socket *s = it->second;
+ ++it;
+
+ if (s->HasFlag(SF_DEAD))
+ {
+ delete s;
+ }
+ }
+ }
+ }
+};
+
+class ModuleSocketEngineSelect : public Module
+{
+ SocketEngineSelect *engine;
+
+ public:
+ ModuleSocketEngineSelect(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetPermanent(true);
+ this->SetType(SOCKETENGINE);
+
+ engine = new SocketEngineSelect();
+ SocketEngine = engine;
+ }
+
+ ~ModuleSocketEngineSelect()
+ {
+ delete engine;
+ SocketEngine = NULL;
+ }
+};
+
+MODULE_INIT(ModuleSocketEngineSelect)
+