X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Scheduler%2FScheduler.cc;h=816e663d17da7b4494ed213220ed6e78d2a253ad;hb=dd9cab12c8a33e57da1dd1104b530e8ea1591c53;hp=f692402b2f88572078f0a4da1e5d7077716d2ed3;hpb=85ab07d100a382467a42e19d741d403a7a96c951;p=senf.git diff --git a/Scheduler/Scheduler.cc b/Scheduler/Scheduler.cc index f692402..816e663 100644 --- a/Scheduler/Scheduler.cc +++ b/Scheduler/Scheduler.cc @@ -79,7 +79,6 @@ #include #include #include "Utils/Exception.hh" -#include "Utils/MicroTime.hh" static const int EPollInitialSize = 16; @@ -92,13 +91,13 @@ prefix_ senf::Scheduler::Scheduler & senf::Scheduler::instance() return instance; } -prefix_ void senf::Scheduler::timeout(unsigned long timeout, TimerCallback const & cb) +prefix_ void senf::Scheduler::timeout(ClockService::clock_type timeout, TimerCallback const & cb) { - timerQueue_.push(TimerSpec(now()+1000*timeout,cb)); + timerQueue_.push(TimerSpec(ClockService::now()+timeout,cb)); } prefix_ senf::Scheduler::Scheduler() - : epollFd_(epoll_create(EPollInitialSize)) + : epollFd_ (epoll_create(EPollInitialSize)) { if (epollFd_<0) throw SystemException(errno); @@ -116,8 +115,6 @@ prefix_ void senf::Scheduler::do_add(int fd, SimpleCallback const & cb, int even if (eventMask & EV_READ) i->second.cb_read = cb; if (eventMask & EV_PRIO) i->second.cb_prio = cb; if (eventMask & EV_WRITE) i->second.cb_write = cb; - if (eventMask & EV_HUP) i->second.cb_hup = cb; - if (eventMask & EV_ERR) i->second.cb_err = cb; epoll_event ev; memset(&ev,0,sizeof(ev)); @@ -137,8 +134,6 @@ prefix_ void senf::Scheduler::do_remove(int fd, int eventMask) if (eventMask & EV_READ) i->second.cb_read = 0; if (eventMask & EV_PRIO) i->second.cb_prio = 0; if (eventMask & EV_WRITE) i->second.cb_write = 0; - if (eventMask & EV_HUP) i->second.cb_hup = 0; - if (eventMask & EV_ERR) i->second.cb_err = 0; epoll_event ev; memset(&ev,0,sizeof(ev)); @@ -163,8 +158,6 @@ prefix_ int senf::Scheduler::EventSpec::epollMask() if (cb_read) mask |= EPOLLIN; if (cb_prio) mask |= EPOLLPRI; if (cb_write) mask |= EPOLLOUT; - if (cb_hup) mask |= EPOLLHUP; - if (cb_err) mask |= EPOLLERR; return mask; } @@ -172,63 +165,64 @@ prefix_ void senf::Scheduler::process() { terminate_ = false; while (! terminate_) { + ClockService::clock_type timeNow = ClockService::now(); - MicroTime timeNow = now(); while ( ! timerQueue_.empty() && timerQueue_.top().timeout <= timeNow ) { timerQueue_.top().cb(); timerQueue_.pop(); } + if (terminate_) return; - int timeout = timerQueue_.empty() ? -1 : int((timerQueue_.top().timeout - timeNow)/1000); + + int timeout (MinTimeout); + if (! timerQueue_.empty()) { + ClockService::clock_type delta ((timerQueue_.top().timeout - timeNow)/1000000UL); + if (deltasecond); + EventSpec spec (i->second); + + unsigned extraFlags (0); + if (ev.events & EPOLLHUP) extraFlags |= EV_HUP; + if (ev.events & EPOLLERR) extraFlags |= EV_ERR; if (ev.events & EPOLLIN) { BOOST_ASSERT(spec.cb_read); - spec.cb_read(EV_READ); + spec.cb_read(EventId(EV_READ | extraFlags)); } else if (ev.events & EPOLLPRI) { BOOST_ASSERT(spec.cb_prio); - spec.cb_prio(EV_PRIO); + spec.cb_prio(EventId(EV_PRIO | extraFlags)); } else if (ev.events & EPOLLOUT) { BOOST_ASSERT(spec.cb_write); - spec.cb_write(EV_WRITE); + spec.cb_write(EventId(EV_WRITE | extraFlags)); } - - else if (ev.events & EPOLLHUP) { - if (spec.cb_hup) - spec.cb_hup(EV_HUP); - else if (ev.events & EPOLLERR) { - /** \fixme This is stupid, if cb_write and cb_read are - the same. The same below. We really have to - exactly define sane semantics of what to do on - EPOLLHUP and EPOLLERR. */ - if (spec.cb_write) spec.cb_write(EV_HUP); - if (spec.cb_read) spec.cb_read(EV_HUP); - } - } - else if (ev.events & EPOLLERR && ! ev.events & EPOLLHUP) { - if (spec.cb_err) - spec.cb_err(EV_ERR); - else { - if (spec.cb_write) spec.cb_write(EV_ERR); - if (spec.cb_read) spec.cb_read(EV_ERR); - } + else { + // This branch is only taken, if HUP or ERR is signaled but none of IN/OUT/PRI. + // In this case we will signal all registered callbacks. The callbacks must be + // prepared to be called multiple times if they are registered to more than + // one event. + if (spec.cb_write) + spec.cb_write(EventId(extraFlags)); + if (spec.cb_prio) + spec.cb_prio(EventId(extraFlags)); + if (spec.cb_read) + spec.cb_read(EventId(extraFlags)); } - } } @@ -242,4 +236,6 @@ prefix_ void senf::Scheduler::process() // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// comment-column: 40 // End: