X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Scheduler%2FScheduler.cc;h=1f946436454a664a4c7f400d981a672380143fcb;hb=8c6fd45554d96f218425b42512579f4bf476e23e;hp=74761daa127cee2ae11dc7f8f02c73c85780123e;hpb=c7ddbbb0bc014bdfe6daef91e2d1c512d77e9fff;p=senf.git diff --git a/Scheduler/Scheduler.cc b/Scheduler/Scheduler.cc index 74761da..1f94643 100644 --- a/Scheduler/Scheduler.cc +++ b/Scheduler/Scheduler.cc @@ -41,6 +41,7 @@ namespace { bool terminate_ (false); + bool running_ (false); } prefix_ void senf::scheduler::terminate() @@ -48,20 +49,61 @@ prefix_ void senf::scheduler::terminate() terminate_ = true; } +prefix_ void senf::scheduler::yield() +{ + senf::scheduler::detail::FIFORunner::instance().yield(); +} + +prefix_ bool senf::scheduler::running() +{ + return running_; +} + +prefix_ senf::ClockService::clock_type senf::scheduler::now() +{ + return running() ? eventTime() : ClockService::now(); +} + +namespace { + + // We don't want try { } catch(...) { ... throw; } since that will make debugging more + // difficult: the stack backtrace for an unexpected exception would always end here. + struct SchedulerScopedInit + { + SchedulerScopedInit() + { + senf::scheduler::detail::FIFORunner::instance().startWatchdog(); + senf::scheduler::detail::SignalDispatcher::instance().unblockSignals(); + senf::scheduler::detail::TimerDispatcher::instance().enable(); + running_ = true; + } + + ~SchedulerScopedInit() + { + senf::scheduler::detail::TimerDispatcher::instance().disable(); + senf::scheduler::detail::SignalDispatcher::instance().blockSignals(); + senf::scheduler::detail::FIFORunner::instance().stopWatchdog(); + running_ = false; + } + }; +} + prefix_ void senf::scheduler::process() { + SchedulerScopedInit initScheduler; terminate_ = false; + detail::TimerDispatcher::instance().reschedule(); while(! terminate_ && ! (detail::FdDispatcher::instance().empty() && detail::TimerDispatcher::instance().empty() && - detail::FileDispatcher::instance().empty())) { - detail::SignalDispatcher::instance().unblockSignals(); - detail::TimerDispatcher::instance().unblockSignals(); + detail::FileDispatcher::instance().empty() && + detail::IdleEventDispatcher::instance().empty()) ) { detail::FdManager::instance().processOnce(); - detail::TimerDispatcher::instance().blockSignals(); - detail::SignalDispatcher::instance().blockSignals(); detail::FileDispatcher::instance().prepareRun(); - detail::EventEventDispatcher::instance().prepareRun(); + detail::EventHookDispatcher::instance().prepareRun(); + detail::TimerDispatcher::instance().prepareRun(); + detail::IdleEventDispatcher::instance().prepareRun(); detail::FIFORunner::instance().run(); + detail::TimerDispatcher::instance().reschedule(); } } @@ -73,9 +115,11 @@ prefix_ void senf::scheduler::restart() detail::TimerDispatcher* tdd (&detail::TimerDispatcher::instance()); detail::SignalDispatcher* sdd (&detail::SignalDispatcher::instance()); detail::FileDispatcher* fld (&detail::FileDispatcher::instance()); - detail::EventEventDispatcher* eed (&detail::EventEventDispatcher::instance()); + detail::IdleEventDispatcher* ied (&detail::IdleEventDispatcher::instance()); + detail::EventHookDispatcher* eed (&detail::EventHookDispatcher::instance()); - eed->~EventEventDispatcher(); + eed->~EventHookDispatcher(); + ied->~IdleEventDispatcher(); fld->~FileDispatcher(); sdd->~SignalDispatcher(); tdd->~TimerDispatcher(); @@ -89,7 +133,8 @@ prefix_ void senf::scheduler::restart() new (tdd) detail::TimerDispatcher(); new (sdd) detail::SignalDispatcher(); new (fld) detail::FileDispatcher(); - new (eed) detail::EventEventDispatcher(); + new (ied) detail::IdleEventDispatcher(); + new (eed) detail::EventHookDispatcher(); } prefix_ bool senf::scheduler::empty() @@ -98,7 +143,20 @@ prefix_ bool senf::scheduler::empty() && detail::TimerDispatcher::instance().empty() && detail::FileDispatcher::instance().empty() && detail::SignalDispatcher::instance().empty() - && detail::EventEventDispatcher::instance().empty(); + && detail::IdleEventDispatcher::instance().empty() + && detail::EventHookDispatcher::instance().empty(); +} + +prefix_ void senf::scheduler::hiresTimers() +{ +#ifdef HAVE_TIMERFD + if (haveScalableHiresTimers()) + detail::TimerDispatcher::instance().timerSource( + std::auto_ptr(new detail::TimerFDTimerSource())); + else +#endif + detail::TimerDispatcher::instance().timerSource( + std::auto_ptr(new detail::POSIXTimerSource())); } /////////////////////////////////////////////////////////////////////////// @@ -107,7 +165,34 @@ prefix_ bool senf::scheduler::empty() prefix_ senf::log::time_type senf::scheduler::LogTimeSource::operator()() const { - return eventTime(); + return senf::scheduler::now(); +} + +/////////////////////////////////////////////////////////////////////////// +// senf::scheduler::BlockSignals + +prefix_ senf::scheduler::BlockSignals::BlockSignals(bool initiallyBlocked) + : blocked_ (false) +{ + ::sigfillset(&allSigs_); + if (initiallyBlocked) + block(); +} + +prefix_ void senf::scheduler::BlockSignals::block() +{ + if (blocked_) + return; + ::sigprocmask(SIG_BLOCK, &allSigs_, &savedSigs_); + blocked_ = true; +} + +prefix_ void senf::scheduler::BlockSignals::unblock() +{ + if (!blocked_) + return; + ::sigprocmask(SIG_SETMASK, &savedSigs_, 0); + blocked_ = false; } ///////////////////////////////cc.e////////////////////////////////////////