Scheduler: Factor out TimerSource from TimerDispatcher and implement POSIXTimerSource
[senf.git] / Scheduler / Scheduler.cc
index 7ba69ef..3203d20 100644 (file)
@@ -35,7 +35,6 @@
 //#include "Scheduler.ih"
 
 // Custom includes
-#include "SignalEvent.hh"
 
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
@@ -49,31 +48,56 @@ 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()
 {
+    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::FdManager::instance().processOnce();
-        detail::TimerDispatcher::instance().blockSignals();
-        detail::SignalDispatcher::instance().blockSignals();
         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()
 {
-    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::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();
     sdd->~SignalDispatcher();
     tdd->~TimerDispatcher();
@@ -87,6 +111,7 @@ prefix_ void senf::scheduler::restart()
     new (tdd) detail::TimerDispatcher();
     new (sdd) detail::SignalDispatcher();
     new (fld) detail::FileDispatcher();
+    new (eed) detail::EventHookDispatcher();
 }
 
 prefix_ bool senf::scheduler::empty()
@@ -94,7 +119,8 @@ prefix_ bool senf::scheduler::empty()
     return detail::FdDispatcher::instance().empty() 
         && detail::TimerDispatcher::instance().empty()
         && detail::FileDispatcher::instance().empty()
-        && detail::SignalDispatcher::instance().empty();
+        && detail::SignalDispatcher::instance().empty()
+        && detail::EventHookDispatcher::instance().empty();
 }
 
 ///////////////////////////////////////////////////////////////////////////