diff options
-rw-r--r-- | include/socketengine_select.h | 4 | ||||
-rw-r--r-- | src/socketengine_select.cpp | 30 | ||||
-rw-r--r-- | src/users.cpp | 1 |
3 files changed, 27 insertions, 8 deletions
diff --git a/include/socketengine_select.h b/include/socketengine_select.h index f6c034091..053ebc8c6 100644 --- a/include/socketengine_select.h +++ b/include/socketengine_select.h @@ -36,6 +36,9 @@ private: /** Because select() does not track an fd list for us between calls, we have one of our own */ std::map<int,int> fds; + /** List of writeable ones (WantWrite()) + */ + bool writeable[MAX_DESCRIPTORS]; /** The read set and write set, populated before each call to select(). */ fd_set wfdset, rfdset; @@ -53,6 +56,7 @@ public: virtual bool DelFd(EventHandler* eh); virtual int DispatchEvents(); virtual std::string GetName(); + virtual void WantWrite(EventHandler* eh); }; /** Creates a SocketEngine diff --git a/src/socketengine_select.cpp b/src/socketengine_select.cpp index 8d0ed446c..7a21fab84 100644 --- a/src/socketengine_select.cpp +++ b/src/socketengine_select.cpp @@ -24,6 +24,7 @@ SelectEngine::SelectEngine(InspIRCd* Instance) : SocketEngine(Instance) ServerInstance->Log(DEBUG,"SelectEngine::SelectEngine()"); EngineHandle = 0; CurrentSetSize = 0; + memset(writeable, 0, sizeof(writeable)); } SelectEngine::~SelectEngine() @@ -57,6 +58,15 @@ bool SelectEngine::AddFd(EventHandler* eh) return true; } +void SelectEngine::WantWrite(EventHandler* eh) +{ + int fd = eh->GetFd(); + + writeable[fd] = true; + + ServerInstance->Log(DEBUG,"Set %d to writeable", fd); +} + bool SelectEngine::DelFd(EventHandler* eh) { int fd = eh->GetFd(); @@ -101,14 +111,11 @@ int SelectEngine::DispatchEvents() for (std::map<int,int>::iterator a = fds.begin(); a != fds.end(); a++) { if (ref[a->second]->Readable()) - { FD_SET (a->second, &rfdset); - } else - { FD_SET (a->second, &wfdset); - } - + if (writeable[a->second]) + FD_SET (a->second, &wfdset); } tval.tv_sec = 0; tval.tv_usec = 50L; @@ -131,8 +138,17 @@ int SelectEngine::DispatchEvents() */ for (int i = 0; i < result; i++) { - ServerInstance->Log(DEBUG,"Handle %s event on fd %d",ev[i]->Readable() ? "read" : "write", ev[i]->GetFd()); - ev[i]->HandleEvent(ev[i]->Readable() ? EVENT_READ : EVENT_WRITE); + ServerInstance->Log(DEBUG,"Handle %s event on fd %d",writeable[ev[i]->GetFd()] || !ev[i]->Readable() ? "write" : "read", ev[i]->GetFd()); + if (writeable[ev[i]->GetFd()]) + { + ev[i]->HandleEvent(EVENT_WRITE); + writeable[ev[i]->GetFd()] = false; + + } + else + { + ev[i]->HandleEvent(ev[i]->Readable() ? EVENT_READ : EVENT_WRITE); + } } return result; diff --git a/src/users.cpp b/src/users.cpp index 808d25a25..067e3068f 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -702,7 +702,6 @@ const char* userrec::GetWriteError() void userrec::Oper(const std::string &opertype) { - this->ServerInstance->SE->WantWrite(this); try { this->modes[UM_OPERATOR] = 1; |