X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fio%2Funix%2Fpoll.cpp;fp=source%2Fio%2Funix%2Fpoll.cpp;h=650f2268e0fd2e419c7624ce76ab8890b6e952a0;hp=0000000000000000000000000000000000000000;hb=609c9a508cfdc7b42c46c4f21d17639204165a00;hpb=b4806214e905752617691f851717033fd3f266c2 diff --git a/source/io/unix/poll.cpp b/source/io/unix/poll.cpp new file mode 100644 index 0000000..650f226 --- /dev/null +++ b/source/io/unix/poll.cpp @@ -0,0 +1,109 @@ +#include +#include +#include +#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::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