terminate_ = true;
}
+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();
+ }
+
+ ~SchedulerScopedInit()
+ {
+ senf::scheduler::detail::TimerDispatcher::instance().disable();
+ senf::scheduler::detail::SignalDispatcher::instance().blockSignals();
+ senf::scheduler::detail::FIFORunner::instance().stopWatchdog();
+ }
+ };
+}
+
prefix_ void senf::scheduler::process()
{
- try {
- detail::FIFORunner::instance().startWatchdog();
- detail::SignalDispatcher::instance().unblockSignals();
- detail::TimerDispatcher::instance().unblockSignals();
- terminate_ = false;
- 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::FIFORunner::instance().run();
- }
+ SchedulerScopedInit initScheduler;
+ terminate_ = false;
+ 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();
}
- catch(...) {
- detail::TimerDispatcher::instance().blockSignals();
- detail::SignalDispatcher::instance().blockSignals();
- detail::FIFORunner::instance().stopWatchdog();
- throw;
- }
- detail::TimerDispatcher::instance().blockSignals();
- detail::SignalDispatcher::instance().blockSignals();
- detail::FIFORunner::instance().stopWatchdog();
}
prefix_ void senf::scheduler::restart()
&& detail::EventHookDispatcher::instance().empty();
}
+prefix_ void senf::scheduler::hiresTimers()
+{
+#ifdef HAVE_TIMERFD
+ if (haveScalableHiresTimers())
+ detail::TimerDispatcher::instance().timerSource(
+ std::auto_ptr<detail::TimerSource>(new detail::TimerFDTimerSource()));
+ else
+#endif
+ detail::TimerDispatcher::instance().timerSource(
+ std::auto_ptr<detail::TimerSource>(new detail::POSIXTimerSource()));
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::schedulerLogTimeSource
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////////////////////////////////////////
#undef prefix_