X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Scheduler%2FScheduler.cc;h=9ea0e481ea8f57df5f98fe04ae167e537c557761;hb=81f84badf27b66dbadec9890646ca1193e998505;hp=2d137819911346fa8b75f71982556d0d770cee2a;hpb=03516e8371a90f908ce54dedb3c874eec7dd08ff;p=senf.git diff --git a/Scheduler/Scheduler.cc b/Scheduler/Scheduler.cc index 2d13781..9ea0e48 100644 --- a/Scheduler/Scheduler.cc +++ b/Scheduler/Scheduler.cc @@ -35,58 +35,154 @@ //#include "Scheduler.ih" // Custom includes -#include "SignalEvent.hh" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ void senf::Scheduler::process() +namespace { + bool terminate_ (false); + bool running_ (false); +} + +prefix_ void senf::scheduler::terminate() +{ + terminate_ = true; +} + +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; - while(! terminate_ && ! (scheduler::detail::FdDispatcher::instance().empty() && - scheduler::detail::TimerDispatcher::instance().empty() && - scheduler::detail::FileDispatcher::instance().empty())) { - scheduler::detail::SignalDispatcher::instance().unblockSignals(); - scheduler::detail::TimerDispatcher::instance().unblockSignals(); - scheduler::FdManager::instance().processOnce(); - scheduler::detail::TimerDispatcher::instance().blockSignals(); - scheduler::detail::SignalDispatcher::instance().blockSignals(); - scheduler::detail::FileDispatcher::instance().prepareRun(); - scheduler::FIFORunner::instance().run(); + running_ = true; + detail::TimerDispatcher::instance().reschedule(); + while(! terminate_ && ! (detail::FdDispatcher::instance().empty() && + detail::TimerDispatcher::instance().empty() && + detail::FileDispatcher::instance().empty())) { + detail::FdManager::instance().processOnce(); + detail::FileDispatcher::instance().prepareRun(); + detail::EventHookDispatcher::instance().prepareRun(); + detail::TimerDispatcher::instance().prepareRun(); + detail::FIFORunner::instance().run(); + detail::TimerDispatcher::instance().reschedule(); } } -prefix_ void senf::Scheduler::restart() +prefix_ void senf::scheduler::restart() { - scheduler::FdManager* fdm (&scheduler::FdManager::instance()); - scheduler::FIFORunner* ffr (&scheduler::FIFORunner::instance()); - scheduler::detail::FdDispatcher* fdd (&scheduler::detail::FdDispatcher::instance()); - scheduler::detail::TimerDispatcher* td (&scheduler::detail::TimerDispatcher::instance()); - scheduler::detail::SignalDispatcher* sd (&scheduler::detail::SignalDispatcher::instance()); - scheduler::detail::FileDispatcher* fld (&scheduler::detail::FileDispatcher::instance()); - + detail::FdManager* fdm (&detail::FdManager::instance()); + detail::FIFORunner* ffr (&detail::FIFORunner::instance()); + detail::FdDispatcher* fdd (&detail::FdDispatcher::instance()); + detail::TimerDispatcher* tdd (&detail::TimerDispatcher::instance()); + detail::SignalDispatcher* sdd (&detail::SignalDispatcher::instance()); + detail::FileDispatcher* fld (&detail::FileDispatcher::instance()); + detail::EventHookDispatcher* eed (&detail::EventHookDispatcher::instance()); + + eed->~EventHookDispatcher(); fld->~FileDispatcher(); - sd->~SignalDispatcher(); - td->~TimerDispatcher(); + sdd->~SignalDispatcher(); + tdd->~TimerDispatcher(); fdd->~FdDispatcher(); ffr->~FIFORunner(); fdm->~FdManager(); - new (fdm) scheduler::FdManager(); - new (ffr) scheduler::FIFORunner(); - new (fdd) scheduler::detail::FdDispatcher(); - new (td) scheduler::detail::TimerDispatcher(); - new (sd) scheduler::detail::SignalDispatcher(); - new (fld) scheduler::detail::FileDispatcher(); + new (fdm) detail::FdManager(); + new (ffr) detail::FIFORunner(); + new (fdd) detail::FdDispatcher(); + new (tdd) detail::TimerDispatcher(); + new (sdd) detail::SignalDispatcher(); + new (fld) detail::FileDispatcher(); + new (eed) detail::EventHookDispatcher(); +} + +prefix_ bool senf::scheduler::empty() +{ + return detail::FdDispatcher::instance().empty() + && detail::TimerDispatcher::instance().empty() + && detail::FileDispatcher::instance().empty() + && detail::SignalDispatcher::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())); } /////////////////////////////////////////////////////////////////////////// -// senf::SchedulerLogTimeSource +// senf::schedulerLogTimeSource -prefix_ senf::log::time_type senf::SchedulerLogTimeSource::operator()() +prefix_ senf::log::time_type senf::scheduler::LogTimeSource::operator()() const { - return Scheduler::instance().eventTime(); + return eventTime(); +} + +/////////////////////////////////////////////////////////////////////////// +// 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////////////////////////////////////////