Scheduler: Factor out TimerSource from TimerDispatcher and implement POSIXTimerSource
[senf.git] / Scheduler / Scheduler.cc
index e7550bb..3203d20 100644 (file)
@@ -48,31 +48,43 @@ prefix_ void senf::scheduler::terminate()
     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();
-        }
-    }
-    catch(...) {
-        detail::TimerDispatcher::instance().blockSignals();
-        detail::SignalDispatcher::instance().blockSignals();
-        detail::FIFORunner::instance().stopWatchdog();
-        throw;
+    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();
     }
-    detail::TimerDispatcher::instance().blockSignals();
-    detail::SignalDispatcher::instance().blockSignals();
-    detail::FIFORunner::instance().stopWatchdog();
 }
 
 prefix_ void senf::scheduler::restart()