--- /dev/null
+/*
+This file is part of libmspframework
+Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+#include "pollable.h"
+#include "poller.h"
+
+using namespace std;
+
+namespace Msp {
+
+Poller::Slot &Poller::add_pollable(Pollable *obj, short events)
+{
+ MutexLock sl(slots_mutex);
+
+ slots.push_back(new Slot(obj, events));
+ if(!pfd_mutex.trylock())
+ {
+ rebuild_pfd();
+ pfd_mutex.unlock();
+ }
+ else
+ dirty=true;
+ return *slots.back();
+}
+
+int Poller::poll(int timeout)
+{
+#ifdef WIN32
+ return 0;
+#else
+ slots_mutex.lock();
+ for(list<Slot *>::iterator i=slots.begin(); i!=slots.end();)
+ {
+ if((*i)->get_object())
+ ++i;
+ else
+ {
+ delete *i;
+ i=slots.erase(i);
+ dirty=true;
+ }
+ }
+
+ pfd_mutex.lock();
+ if(dirty)
+ {
+ rebuild_pfd();
+ dirty=false;
+ }
+ slots_mutex.unlock();
+
+ int result=::poll(&pfd[0], pfd.size(), timeout);
+
+ if(result>0)
+ {
+ list<Slot *>::iterator j=slots.begin();
+ for(vector<pollfd>::iterator i=pfd.begin(); i!=pfd.end(); ++i)
+ {
+ if(i->revents&POLLNVAL)
+ dirty=true;
+ else if(i->revents)
+ {
+ while(j!=slots.end() && (!(*j)->get_object() || (*j)->get_object()->get_fd()!=i->fd))
+ ++j;
+ if(j==slots.end())
+ break;
+ (*j)->signal_event.emit(i->revents);
+ }
+ }
+ }
+
+ pfd_mutex.unlock();
+
+ return result;
+#endif
+}
+
+void Poller::rebuild_pfd()
+{
+ pfd.clear();
+ pfd.reserve(slots.size());
+ for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
+ {
+ if(!(*i)->get_object() || (*i)->get_object()->get_fd()<0)
+ continue;
+
+ pfd.push_back(pollfd());
+ pfd.back().fd=(*i)->get_object()->get_fd();
+ pfd.back().events=(*i)->get_events();
+ }
+}
+
+Poller::Slot::Slot(Pollable *o, short e):
+ obj(o),
+ events(e)
+{
+ obj->signal_deleted.connect(sigc::mem_fun(this, &Slot::obj_deleted));
+}
+
+} // namespace Msp