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);
}
Poller::Poller():
priv(new Private),
+ events_changed(false),
objs_changed(false)
{ }
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()
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();
#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>
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();
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);
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)
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;
}
}
#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)
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");