X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fvisitor%2Fhdsd%2Fscd%2Fscd_sock_poller.cpp;fp=dol%2Fsrc%2Fdol%2Fvisitor%2Fhdsd%2Fscd%2Fscd_sock_poller.cpp;h=1cff37451416371ca122c2987552c24306c93384;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/visitor/hdsd/scd/scd_sock_poller.cpp b/dol/src/dol/visitor/hdsd/scd/scd_sock_poller.cpp new file mode 100644 index 0000000..1cff374 --- /dev/null +++ b/dol/src/dol/visitor/hdsd/scd/scd_sock_poller.cpp @@ -0,0 +1,201 @@ +#include "scd_sock_poller.h" + +#include +#include +#include +#include + +#include "scd_exception.h" +#include "scd_logging.h" + + +bool scd_sock_poller::register_handler(scd_sock_ev_handler_if& handler, + sock_ev events) +{ + // can not register the same handler twice + if (_handler_exists(handler)) + { + scd_warn("socket handler already registered while registering"); + return false; + } + + // register handler + _handlers.push_back(&handler); + + // register socket and events + struct pollfd fd; + fd.fd = handler.get_sock()._socket; + fd.events = events; + _events.push_back(fd); + return true; + +} // register_handler() + + +bool scd_sock_poller::remove_handler(const scd_sock_ev_handler_if &handler) +{ + int idx = _get_index(handler); + + // check if handler was found + if (idx == -1) + { + scd_warn("socket handler not registered while removing poll handler"); + return false; + } + + // remove events and handler from vectors + _events.erase(_events.begin() + idx); + _handlers.erase(_handlers.begin() + idx); + + return true; + +} // remove_handler() + + +bool scd_sock_poller::set_ev(const scd_sock_ev_handler_if &handler, + sock_ev events) +{ + int idx = _get_index(handler); + + if (idx == -1) + { + scd_warn("socket handler not registered while setting poll events"); + return false; + } + + _events[idx].events = events; + + return true; +} // set_ev() + + +bool scd_sock_poller::get_ev(const scd_sock_ev_handler_if &handler, + sock_ev &events) const +{ + int idx = _get_index(handler); + + if (idx == -1) + { + scd_warn("socket handler not registered while getting poll events"); + return false; + } + + events = _events[idx].events; + + return true; + +} // get_ev() + + +bool scd_sock_poller::wait(int ms) +{ + int ret = _poll(ms); + if (ret > 0) + return true; + else + return false; +} + + +bool scd_sock_poller::process() +{ + int ret = _poll(0); + + if (ret != 0) // events occured + { + _callback(); + return true; + } + else + return false; + +} // process() + + +void scd_sock_poller::wait_process() +{ + _poll(-1); + _callback(); + +} // wait_process() + + +bool scd_sock_poller::_handler_exists(const scd_sock_ev_handler_if &handler) + const +{ + std::vector::const_iterator iter; + + iter = std::find(_handlers.begin(), _handlers.end(), &handler); + + if (iter == _handlers.end()) + return false; + else + return true; + +} // _handler_exists() + + +int scd_sock_poller::_get_index(const scd_sock_ev_handler_if &handler) const +{ + std::vector::const_iterator iter; + + iter = std::find(_handlers.begin(), _handlers.end(), &handler); + + if (iter == _handlers.end()) + { + // handler not found + return -1; + } + else + { + // return index (random access iterator) + return iter - _handlers.begin(); + } + +} // _get_index() + + +int scd_sock_poller::_poll(int ms) +{ + int ret; + + if (ms < 0 && _events.size() == 0) + { + scd_debug("immediately returning form infinite poll: no events to watch"); + return 0; + } + + do + { + ret = poll(&_events[0], _events.size(), ms); + if (ret == -1 && errno != EINTR) + { + std::string error("poll(): "); + error += std::string(strerror(errno)); + throw scd_exception(error); + } + } + while (ret == -1 && errno == EINTR); + + return ret; + +} // _poll() + + +void scd_sock_poller::_callback() +{ + /* called handlers might remove themselves. as the order + * should not break we operate on copies here */ + std::vector events_cpy = _events; + std::vector handlers_cpy = _handlers; + + // for all handlers + for (int i=0; i callback handler + handlers_cpy[i]->handle_sock_ev(events_cpy[i].revents); + } + } // for all events +} // _callback()