Use vectors for storage in Poller
authorMikko Rasa <tdb@tdb.fi>
Fri, 27 Sep 2019 19:34:05 +0000 (22:34 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 27 Sep 2019 23:31:43 +0000 (02:31 +0300)
source/io/eventdispatcher.cpp
source/io/poll.cpp
source/io/poll.h
source/io/unix/poll.cpp
source/io/windows/poll.cpp

index 47aafa52818eacf85fbd815c17db31697314255a..550043f4cffdd99f47144a0af5a7e32686cabad1 100644 (file)
@@ -63,8 +63,8 @@ void EventDispatcher::tick(const Time::Timer &timer)
 
 void EventDispatcher::dispatch()
 {
-       const Poller::SlotList &result = poller.get_result();
-       for(Poller::SlotList::const_iterator i=result.begin(); i!=result.end(); ++i)
+       const vector<Poller::Slot> &result = poller.get_result();
+       for(vector<Poller::Slot>::const_iterator i=result.begin(); i!=result.end(); ++i)
                i->object->event(i->events);
 }
 
index 6da777cf4470778f4e6401dbcc39f1a3a539b4e7..2e33502e8433969059dccdd1ecbde834a3e6aff7 100644 (file)
@@ -10,6 +10,7 @@ namespace IO {
 
 Poller::Poller():
        priv(new Private),
+       events_changed(false),
        objs_changed(false)
 { }
 
@@ -24,26 +25,31 @@ void Poller::set_object(EventObject &obj, PollEvent ev)
        if(ev)
                obj.get_event_handle();
 
-       EventMap::iterator i = objects.find(&obj);
-       if(i!=objects.end())
-       {
-               if(ev)
-                       i->second = ev;
-               else
-                       objects.erase(i);
+       for(vector<Slot>::iterator i=objects.begin(); i!=objects.end(); ++i)
+               if(i->object==&obj)
+               {
+                       if(ev)
+                               i->events = ev;
+                       else
+                       {
+                               *i = objects.back();
+                               objects.pop_back();
+                               objs_changed = true;
+                       }
+                       events_changed = true;
+                       return;
+               }
+
+       if(!ev)
+               return;
 
-               objs_changed = true;
-       }
-       else if(ev)
-       {
 #ifdef _WIN32
-               if(objects.size()>=MAXIMUM_WAIT_OBJECTS)
-                       throw logic_error("Maximum number of wait objects reached");
+       if(objects.size()>=MAXIMUM_WAIT_OBJECTS)
+               throw logic_error("Maximum number of wait objects reached");
 #endif
-               objects.insert(EventMap::value_type(&obj, ev));
 
-               objs_changed = true;
-       }
+       objects.push_back(Slot(&obj, ev));
+       objs_changed = true;
 }
 
 int Poller::poll()
@@ -61,8 +67,12 @@ int Poller::poll(const Time::TimeDelta &timeout)
 
 int Poller::do_poll(int timeout)
 {
-       if(objs_changed)
+       if(objs_changed || events_changed)
+       {
                rebuild_array();
+               events_changed = false;
+               objs_changed = false;
+       }
 
        poll_result.clear();
 
index b65166d24bffb7cf8d7aea7e30f09f525c7b84d2..fdb68c515bbe35e0e05cafdde93e59c625a7bced 100644 (file)
@@ -1,9 +1,9 @@
 #ifndef MSP_IO_POLL_H_
 #define MSP_IO_POLL_H_
 
-#include <list>
 #include <map>
 #include <vector>
+#include <msp/core/attributes.h>
 #include <msp/core/noncopyable.h>
 #include <msp/time/timedelta.h>
 
@@ -43,16 +43,15 @@ public:
                Slot(EventObject *o, PollEvent e): object(o), events(e) { }
        };
 
-       typedef std::list<Slot> SlotList;
+       typedef std::vector<Slot> SlotList DEPRECATED;
 private:
-       typedef std::map<EventObject *, PollEvent> EventMap;
-
        struct Private;
 
-       EventMap objects;
+       std::vector<Slot> objects;
        Private *priv;
+       bool events_changed;
        bool objs_changed;
-       SlotList poll_result;
+       std::vector<Slot> poll_result;
 
 public:
        Poller();
@@ -66,7 +65,7 @@ private:
        int do_poll(int);
        void platform_poll(int);
 public:
-       const SlotList &get_result() const { return poll_result; }
+       const std::vector<Slot> &get_result() const { return poll_result; }
 };
 
 PollEvent poll(EventObject &, PollEvent);
index 6272b4dbf143e26aba3331117e284d1b690dbac7..0fb9d22e03919476e95d52e09ca5faf10088241f 100644 (file)
@@ -57,17 +57,24 @@ namespace IO {
 
 void Poller::rebuild_array()
 {
-       priv->pfd.clear();
+       if(objs_changed)
+       {
+               priv->pfd.clear();
+               priv->pfd.reserve(objects.size());
 
-       for(EventMap::iterator i=objects.begin(); i!=objects.end(); ++i)
+               for(vector<Slot>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
+               {
+                       pollfd p;
+                       p.fd = *i->object->get_event_handle();
+                       p.events = sys_poll_event(i->events);
+                       priv->pfd.push_back(p);
+               }
+       }
+       else
        {
-               pollfd p;
-               p.fd = *i->first->get_event_handle();
-               p.events = sys_poll_event(i->second);
-               priv->pfd.push_back(p);
+               for(unsigned i=0; i<objects.size(); ++i)
+                       priv->pfd[i].events = sys_poll_event(objects[i].events);
        }
-
-       objs_changed = false;
 }
 
 void Poller::platform_poll(int timeout)
@@ -81,11 +88,10 @@ void Poller::platform_poll(int timeout)
                        throw system_error("poll");
        }
 
-       EventMap::iterator j = objects.begin();
-       for(vector<pollfd>::iterator i=priv->pfd.begin(); (i!=priv->pfd.end() && ret>0); ++i, ++j)
-               if(i->revents)
+       for(unsigned i=0; (i<objects.size() && ret>0); ++i)
+               if(priv->pfd[i].revents)
                {
-                       poll_result.push_back(Slot(j->first, poll_event_from_sys(i->revents)));
+                       poll_result.push_back(Slot(objects[i].object, poll_event_from_sys(priv->pfd[i].revents)));
                        --ret;
                }
 }
index e67225805f3964a970f6e6d8fb93f82cb616d376..b3ee8ec9dda104712075891d33127b052b892885 100644 (file)
@@ -5,17 +5,21 @@
 #include "poll.h"
 #include "poll_platform.h"
 
+using namespace std;
+
 namespace Msp {
 namespace IO {
 
 void Poller::rebuild_array()
 {
-       priv->handles.clear();
+       if(!objs_changed)
+               return;
 
-       for(EventMap::iterator i=objects.begin(); i!=objects.end(); ++i)
-               priv->handles.push_back(*i->first->get_event_handle());
+       priv->handles.clear();
+       priv->handles.reserve(objects.size());
 
-       objs_changed = false;
+       for(vector<Slot>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
+               priv->handles.push_back(*i->object->get_event_handle());
 }
 
 void Poller::platform_poll(int timeout)
@@ -26,9 +30,8 @@ void Poller::platform_poll(int timeout)
        DWORD ret = WaitForMultipleObjects(priv->handles.size(), &priv->handles.front(), false, timeout);
        if(/*ret>=WAIT_OBJECT_0 &&*/ ret<WAIT_OBJECT_0+priv->handles.size())
        {
-               EventMap::iterator i = objects.begin();
-               advance(i, ret-WAIT_OBJECT_0);
-               poll_result.push_back(Slot(i->first, i->second));
+               const Slot &slot = objects[ret-WAIT_OBJECT_0];
+               poll_result.push_back(slot);
        }
        else if(ret==WAIT_FAILED)
                throw system_error("WaitForMultipleObjects");