From: Mikko Rasa Date: Fri, 27 Sep 2019 19:34:05 +0000 (+0300) Subject: Use vectors for storage in Poller X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=commitdiff_plain;h=292aed8e23ea543b089d5f2a73000de4640befe7 Use vectors for storage in Poller --- diff --git a/source/io/eventdispatcher.cpp b/source/io/eventdispatcher.cpp index 47aafa5..550043f 100644 --- a/source/io/eventdispatcher.cpp +++ b/source/io/eventdispatcher.cpp @@ -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 &result = poller.get_result(); + for(vector::const_iterator i=result.begin(); i!=result.end(); ++i) i->object->event(i->events); } diff --git a/source/io/poll.cpp b/source/io/poll.cpp index 6da777c..2e33502 100644 --- a/source/io/poll.cpp +++ b/source/io/poll.cpp @@ -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::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(); diff --git a/source/io/poll.h b/source/io/poll.h index b65166d..fdb68c5 100644 --- a/source/io/poll.h +++ b/source/io/poll.h @@ -1,9 +1,9 @@ #ifndef MSP_IO_POLL_H_ #define MSP_IO_POLL_H_ -#include #include #include +#include #include #include @@ -43,16 +43,15 @@ public: Slot(EventObject *o, PollEvent e): object(o), events(e) { } }; - typedef std::list SlotList; + typedef std::vector SlotList DEPRECATED; private: - typedef std::map EventMap; - struct Private; - EventMap objects; + std::vector objects; Private *priv; + bool events_changed; bool objs_changed; - SlotList poll_result; + std::vector 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 &get_result() const { return poll_result; } }; PollEvent poll(EventObject &, PollEvent); diff --git a/source/io/unix/poll.cpp b/source/io/unix/poll.cpp index 6272b4d..0fb9d22 100644 --- a/source/io/unix/poll.cpp +++ b/source/io/unix/poll.cpp @@ -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::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; ipfd[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::iterator i=priv->pfd.begin(); (i!=priv->pfd.end() && ret>0); ++i, ++j) - if(i->revents) + for(unsigned i=0; (i0); ++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; } } diff --git a/source/io/windows/poll.cpp b/source/io/windows/poll.cpp index e672258..b3ee8ec 100644 --- a/source/io/windows/poll.cpp +++ b/source/io/windows/poll.cpp @@ -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::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 &&*/ rethandles.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");