From c11ec1cd3867fc6759fadb8143df676406b3e3e7 Mon Sep 17 00:00:00 2001 From: danieldg Date: Wed, 9 Sep 2009 19:28:42 +0000 Subject: [PATCH] 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 --- include/socketengines/socketengine_select.h | 4 +-- 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 fds; + std::set fds; /** List of writeable ones (WantWrite()) */ - bool* writeable; + std::vector 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::iterator t = fds.find(fd); + std::set::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::iterator a = fds.begin(); a != fds.end(); a++) + for (std::set::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::iterator a = fds.begin(); a != fds.end(); a++) + std::vector copy(fds.begin(), fds.end()); + for (std::vector::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)) -- 2.39.5