X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fio%2Fpoll.cpp;h=a5d2d023c81d3f1ae730fc69d8d903b5546926db;hp=a58090792fcb06cf9c4a2a9049159ac7324524a8;hb=242a4a9abe1e1113b5eb39aa751aa054f696d7be;hpb=b4806214e905752617691f851717033fd3f266c2 diff --git a/source/io/poll.cpp b/source/io/poll.cpp index a580907..a5d2d02 100644 --- a/source/io/poll.cpp +++ b/source/io/poll.cpp @@ -1,108 +1,16 @@ -#include #include -#ifndef WIN32 -#include -#endif -#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"); - -#ifndef WIN32 - if(event&P_INPUT) - result |= POLLIN; - if(event&P_PRIO) - result |= POLLPRI; - if(event&P_OUTPUT) - result |= POLLOUT; -#endif - - return result; -} - -inline PollEvent poll_event_from_sys(int event) -{ - PollEvent result = P_NONE; - -#ifdef WIN32 - (void)event; -#else - 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; -#endif - - return result; -} - -inline PollEvent do_poll(EventObject &obj, PollEvent pe, int timeout) -{ -#ifdef WIN32 - if(timeout<0) - timeout = INFINITE; - - DWORD ret = WaitForSingleObject(*obj.get_event_handle(), timeout); - if(ret==WAIT_OBJECT_0) - return pe; - else if(ret==WAIT_FAILED) - throw system_error("WaitForSingleObject"); - - return P_NONE; -#else - 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); -#endif -} - -} - - namespace Msp { namespace IO { -struct Poller::Private -{ -#ifdef WIN32 - vector handles; -#else - vector pfd; -#endif -}; - - Poller::Poller(): priv(new Private), + events_changed(false), objs_changed(false) { } @@ -117,34 +25,39 @@ 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; + } - objs_changed = true; - } - else if(ev) - { -#ifdef WIN32 - if(objects.size()>=MAXIMUM_WAIT_OBJECTS) - throw logic_error("Maximum number of wait objects reached"); + if(!ev) + return; + +#ifdef _WIN32 + 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(PolledObject(&obj, ev)); + objs_changed = true; } -int Poller::poll() +unsigned Poller::poll() { return do_poll(-1); } -int Poller::poll(const Time::TimeDelta &timeout) +unsigned Poller::poll(const Time::TimeDelta &timeout) { if(timeout(timeout/Time::msec)); } -void Poller::rebuild_array() +unsigned Poller::do_poll(int timeout) { -#ifdef WIN32 - priv->handles.clear(); - - for(EventMap::iterator i=objects.begin(); i!=objects.end(); ++i) - priv->handles.push_back(*i->first->get_event_handle()); -#else - priv->pfd.clear(); - - for(EventMap::iterator i=objects.begin(); i!=objects.end(); ++i) + if(objs_changed || events_changed) { - pollfd p; - p.fd = *i->first->get_event_handle(); - p.events = sys_poll_event(i->second); - priv->pfd.push_back(p); - } -#endif - - objs_changed = false; -} - -int Poller::do_poll(int timeout) -{ - if(objs_changed) rebuild_array(); - - poll_result.clear(); - -#ifdef WIN32 - if(timeout<0) - timeout = INFINITE; - - 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)); - - return 1; + events_changed = false; + objs_changed = false; } - else if(ret==WAIT_FAILED) - throw system_error("WaitForMultipleObjects"); - return 0; -#else - int ret = ::poll(&priv->pfd.front(), priv->pfd.size(), timeout); - if(ret==-1) - { - if(errno==EINTR) - return 0; - else - throw system_error("poll"); - } + poll_result.clear(); - int n = ret; - EventMap::iterator j = objects.begin(); - for(vector::iterator i=priv->pfd.begin(); (i!=priv->pfd.end() && n>0); ++i, ++j) - if(i->revents) - { - poll_result.push_back(Slot(j->first, poll_event_from_sys(i->revents))); - --n; - } + platform_poll(timeout); - return ret; -#endif + return poll_result.size(); } +PollEvent platform_poll(EventObject &, PollEvent, int); + PollEvent poll(EventObject &obj, PollEvent pe) { - return do_poll(obj, pe, -1); + return platform_poll(obj, pe, -1); } PollEvent poll(EventObject &obj, PollEvent pe, const Time::TimeDelta &timeout) @@ -232,7 +94,7 @@ PollEvent poll(EventObject &obj, PollEvent pe, const Time::TimeDelta &timeout) if(timeout(timeout/Time::msec)); + return platform_poll(obj, pe, static_cast(timeout/Time::msec)); } } // namespace IO