]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Fix invalid iterator in select socketengine, clean up its memory use a bit too
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Wed, 9 Sep 2009 19:28:42 +0000 (19:28 +0000)
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Wed, 9 Sep 2009 19:28:42 +0000 (19:28 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11687 e03df62e-2008-0410-955e-edbf42e46eb7

include/socketengines/socketengine_select.h
src/socketengines/socketengine_select.cpp

index f50eb8d5df49fdb888011f2e4a9980d32a9b7ad2..a248e8a8e2999493e1cd5ea6b81552d14b061273 100644 (file)
@@ -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;
index 48d2bbf81c982ae1dcc95a53c8ca3ed10e0c9dd9..8c41df11b745bc5e585a4270d5875d07aae6569f 100644 (file)
@@ -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))