diff options
author | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-09-09 19:28:42 +0000 |
---|---|---|
committer | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-09-09 19:28:42 +0000 |
commit | c11ec1cd3867fc6759fadb8143df676406b3e3e7 (patch) | |
tree | 3b5c07a6e06ff17e57b50df1db02416569d0b5ad | |
parent | d5411d06255ea264791631538642619d13e129aa (diff) |
Fix invalid iterator in select socketengine, clean up its memory use a bit too
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11687 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r-- | include/socketengines/socketengine_select.h | 4 | ||||
-rw-r--r-- | src/socketengines/socketengine_select.cpp | 27 |
2 files changed, 15 insertions, 16 deletions
diff --git a/include/socketengines/socketengine_select.h b/include/socketengines/socketengine_select.h index f50eb8d5d..a248e8a8e 100644 --- a/include/socketengines/socketengine_select.h +++ b/include/socketengines/socketengine_select.h @@ -33,10 +33,10 @@ class SelectEngine : public SocketEngine private: /** Because select() does not track an fd list for us between calls, we have one of our own */ - std::map<int,int> fds; + std::set<int> fds; /** List of writeable ones (WantWrite()) */ - bool* writeable; + std::vector<bool> writeable; /** The read set and write set, populated before each call to select(). */ fd_set wfdset, rfdset, errfdset; diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp index 48d2bbf81..8c41df11b 100644 --- a/src/socketengines/socketengine_select.cpp +++ b/src/socketengines/socketengine_select.cpp @@ -24,8 +24,7 @@ SelectEngine::SelectEngine(InspIRCd* Instance) : SocketEngine(Instance) EngineHandle = 0; CurrentSetSize = 0; - writeable = new bool [GetMaxFds()]; - memset(writeable, 0, sizeof(writeable)); + writeable.assign(GetMaxFds(), false); ref = new EventHandler* [GetMaxFds()]; memset(ref, 0, GetMaxFds() * sizeof(EventHandler*)); } @@ -47,7 +46,7 @@ bool SelectEngine::AddFd(EventHandler* eh) if (ref[fd]) return false; - fds[fd] = fd; + fds.insert(fd); ref[fd] = eh; CurrentSetSize++; @@ -67,7 +66,7 @@ bool SelectEngine::DelFd(EventHandler* eh, bool force) if ((fd < 0) || (fd > GetMaxFds() - 1)) return false; - std::map<int,int>::iterator t = fds.find(fd); + std::set<int>::iterator t = fds.find(fd); if (t != fds.end()) fds.erase(t); @@ -100,21 +99,21 @@ int SelectEngine::DispatchEvents() FD_ZERO(&errfdset); /* Populate the select FD set (this is why select sucks compared to epoll, kqueue, IOCP) */ - for (std::map<int,int>::iterator a = fds.begin(); a != fds.end(); a++) + for (std::set<int>::iterator a = fds.begin(); a != fds.end(); a++) { - if (ref[a->second]->Readable()) + if (ref[*a]->Readable()) /* Read notifications */ - FD_SET (a->second, &rfdset); + FD_SET (*a, &rfdset); else /* Write notifications */ - FD_SET (a->second, &wfdset); + FD_SET (*a, &wfdset); /* Explicitly one-time writeable */ - if (writeable[a->second]) - FD_SET (a->second, &wfdset); + if (writeable[*a]) + FD_SET (*a, &wfdset); /* All sockets must receive error notifications regardless */ - FD_SET (a->second, &errfdset); + FD_SET (*a, &errfdset); } /* One second waits */ @@ -127,10 +126,10 @@ int SelectEngine::DispatchEvents() if (sresult < 1) return 0; - /* Safe assumption (as of 1.1 anyway) that a socket can't remove itself from the list in the middle of the loop */ - for (std::map<int,int>::iterator a = fds.begin(); a != fds.end(); a++) + std::vector<int> copy(fds.begin(), fds.end()); + for (std::vector<int>::iterator a = copy.begin(); a != copy.end(); a++) { - EventHandler* ev = ref[a->second]; + EventHandler* ev = ref[*a]; if (ev) { if (FD_ISSET (ev->GetFd(), &errfdset)) |