summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/socketengine_select.h4
-rw-r--r--src/socketengine_select.cpp30
-rw-r--r--src/users.cpp1
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;