]> git.tdb.fi Git - libs/core.git/blobdiff - source/io/unix/poll.cpp
Move most platform-specific code into overlay directories
[libs/core.git] / source / io / unix / poll.cpp
diff --git a/source/io/unix/poll.cpp b/source/io/unix/poll.cpp
new file mode 100644 (file)
index 0000000..650f226
--- /dev/null
@@ -0,0 +1,109 @@
+#include <cerrno>
+#include <msp/core/systemerror.h>
+#include <poll.h>
+#include "eventobject.h"
+#include "handle.h"
+#include "handle_private.h"
+#include "poll.h"
+#include "poll_platform.h"
+
+using namespace std;
+
+namespace {
+
+using namespace Msp;
+using namespace Msp::IO;
+
+inline short int sys_poll_event(PollEvent event)
+{
+       int result = 0;
+
+       if(event&~(P_INPUT|P_PRIO|P_OUTPUT))
+               throw invalid_argument("sys_poll_event");
+
+       if(event&P_INPUT)
+               result |= POLLIN;
+       if(event&P_PRIO)
+               result |= POLLPRI;
+       if(event&P_OUTPUT)
+               result |= POLLOUT;
+
+       return result;
+}
+
+inline PollEvent poll_event_from_sys(int event)
+{
+       PollEvent result = P_NONE;
+
+       if(event&POLLIN)
+               result = result|P_INPUT;
+       if(event&POLLPRI)
+               result = result|P_PRIO;
+       if(event&POLLOUT)
+               result = result|P_OUTPUT;
+       if(event&POLLERR)
+               result = result|P_ERROR;
+
+       return result;
+}
+
+}
+
+
+namespace Msp {
+namespace IO {
+
+void Poller::rebuild_array()
+{
+       priv->pfd.clear();
+
+       for(EventMap::iterator i=objects.begin(); i!=objects.end(); ++i)
+       {
+               pollfd p;
+               p.fd = *i->first->get_event_handle();
+               p.events = sys_poll_event(i->second);
+               priv->pfd.push_back(p);
+       }
+
+       objs_changed = false;
+}
+
+void Poller::platform_poll(int timeout)
+{
+       int ret = ::poll(&priv->pfd.front(), priv->pfd.size(), timeout);
+       if(ret==-1)
+       {
+               if(errno==EINTR)
+                       return;
+               else
+                       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)
+               {
+                       poll_result.push_back(Slot(j->first, poll_event_from_sys(i->revents)));
+                       --ret;
+               }
+}
+
+
+PollEvent platform_poll(EventObject &obj, PollEvent pe, int timeout)
+{
+       pollfd pfd = { *obj.get_event_handle(), sys_poll_event(pe), 0 };
+
+       int ret = ::poll(&pfd, 1, timeout);
+       if(ret==-1)
+       {
+               if(errno==EINTR)
+                       return P_NONE;
+               else
+                       throw system_error("poll");
+       }
+
+       return poll_event_from_sys(pfd.revents);
+}
+
+} // namespace IO
+} // namespace Msp