moved statistics classes from NetEmu to SENF
[senf.git] / Scheduler / FIFORunner.cc
index 545b4ae..a6fb824 100644 (file)
 // Custom includes
 #include <signal.h>
 #include <time.h>
+#include <boost/lambda/lambda.hpp>
 #include "../Utils/Exception.hh"
 #include "../Utils/senfassert.hh"
+#include "../Utils/ScopeExit.hh"
 
 //#include "FIFORunner.mpp"
 #define prefix_
@@ -38,7 +40,7 @@
 
 prefix_ senf::scheduler::detail::FIFORunner::FIFORunner()
     : tasks_ (), next_ (tasks_.end()), watchdogRunning_ (false), watchdogMs_ (1000), 
-      watchdogCount_(0), hangCount_ (0)
+      watchdogAbort_ (false), watchdogCount_(0), hangCount_ (0)
 {
     struct sigevent ev;
     ::memset(&ev, 0, sizeof(ev));
@@ -73,18 +75,20 @@ prefix_ senf::scheduler::detail::FIFORunner::~FIFORunner()
 
 prefix_ void senf::scheduler::detail::FIFORunner::startWatchdog()
 {
-    struct itimerspec timer;
-    ::memset(&timer, 0, sizeof(timer));
-
-    timer.it_interval.tv_sec = watchdogMs_ / 1000;
-    timer.it_interval.tv_nsec = (watchdogMs_ % 1000) * 1000000ul;
-    timer.it_value.tv_sec = timer.it_interval.tv_sec;
-    timer.it_value.tv_nsec = timer.it_interval.tv_nsec;
-
-    if (timer_settime(watchdogId_, 0, &timer, 0) < 0)
-        SENF_THROW_SYSTEM_EXCEPTION("timer_settime()");
+    if (watchdogMs_ > 0) {
+        struct itimerspec timer;
+        ::memset(&timer, 0, sizeof(timer));
+
+        timer.it_interval.tv_sec = watchdogMs_ / 1000;
+        timer.it_interval.tv_nsec = (watchdogMs_ % 1000) * 1000000ul;
+        timer.it_value.tv_sec = timer.it_interval.tv_sec;
+        timer.it_value.tv_nsec = timer.it_interval.tv_nsec;
+        
+        if (timer_settime(watchdogId_, 0, &timer, 0) < 0)
+            SENF_THROW_SYSTEM_EXCEPTION("timer_settime()");
 
-    watchdogRunning_ = true;
+        watchdogRunning_ = true;
+    }
 }
 
 prefix_ void senf::scheduler::detail::FIFORunner::stopWatchdog()
@@ -143,7 +147,6 @@ prefix_ void senf::scheduler::detail::FIFORunner::run()
     run(f, l);
 }
 
-
 prefix_ void senf::scheduler::detail::FIFORunner::run(TaskList::iterator f, TaskList::iterator l)
 {
     if (f == l)
@@ -164,32 +167,30 @@ prefix_ void senf::scheduler::detail::FIFORunner::run(TaskList::iterator f, Task
     tasks_.insert(l, null);
     TaskList::iterator end (TaskList::current(null));
     next_ = f;
-    try {
-        while (next_ != end) {
-            TaskInfo & task (*next_);
-            if (task.runnable_) {
-                task.runnable_ = false;
-                runningName_ = task.name();
-#           ifdef SENF_DEBUG
-                runningBacktrace_ = task.backtrace_;
-#           endif
-                TaskList::iterator i (next_);
-                ++ next_;
-                tasks_.splice(l, tasks_, i);
-                watchdogCount_ = 1;
-                task.run();
-            }
-            else
-                ++ next_;
+
+    using namespace boost::lambda;
+    ScopeExit atExit ((
+                          var(watchdogCount_) = 0, 
+                          var(next_) = l
+                          ));
+    
+    while (next_ != end) {
+        TaskInfo & task (*next_);
+        if (task.runnable_) {
+            task.runnable_ = false;
+            runningName_ = task.name();
+#       ifdef SENF_DEBUG
+            runningBacktrace_ = task.backtrace_;
+#       endif
+            TaskList::iterator i (next_);
+            ++ next_;
+            tasks_.splice(l, tasks_, i);
+            watchdogCount_ = 1;
+            task.run();
         }
+        else
+            ++ next_;
     }
-    catch (...) {
-        watchdogCount_ = 0;
-        next_ = l;
-        throw;
-    }
-    watchdogCount_ = 0;
-    next_ = l;
 }
 
 prefix_ senf::scheduler::detail::FIFORunner::TaskList::iterator
@@ -221,6 +222,8 @@ prefix_ void senf::scheduler::detail::FIFORunner::watchdog(int, siginfo_t * si,
             write(1, runner.runningBacktrace_.c_str(), runner.runningBacktrace_.size());
 #endif
             write(1, "\n", 1);
+            if (runner.watchdogAbort_)
+                assert(false);
         }
     }
 }