replaced all BOOST_CHECK_NO_THROW with SENF_CHECK_NO_THROW
[senf.git] / Scheduler / Scheduler.hh
index af07c48..033c016 100644 (file)
     \brief Scheduler public header
  */
 
-#ifndef HH_Scheduler_
-#define HH_Scheduler_ 1
+#ifndef HH_SENF_Scheduler_Scheduler_
+#define HH_SENF_Scheduler_Scheduler_ 1
 
 // Custom includes
+#include <boost/utility.hpp>
 #include "../Utils/Logger/SenfLog.hh"
 #include "FdEvent.hh"
 #include "TimerEvent.hh"
 #include "SignalEvent.hh"
+#include "EventHook.hh"
 
 //#include "scheduler.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -64,6 +66,7 @@ namespace senf {
     \li senf::scheduler::FdEvent for file descriptor events
     \li senf::scheduler::TimerEvent for single-shot deadline timer events
     \li senf::scheduler::SignalEvent for UNIX signal events
+    \li senf::scheduler::EventHook for a special event hook
 
     These instance are owned and managed by the user of the scheduler \e not by the scheduler so the
     RAII concept can be used.
@@ -227,9 +230,42 @@ namespace scheduler {
     /** \brief Current task watchdog timeout */
     unsigned taskTimeout(); 
 
-    /** \brief Number of watchdog events */
+    /** \brief Number of watchdog events 
+
+        calling hangCount() will reset the counter to 0
+     */
     unsigned hangCount(); 
 
+    /** \brief Switch to using hi resolution timers
+        
+        By default, timers are implemented directly using epoll. This however restricts the timer
+        resolution to that of the kernel HZ value.
+
+        High resolution timers are implemented either using POSIX timers or, when available, using
+        the Linux special \c timerfd() syscall.
+
+        POSIX timers are delivered using signals. A high timer load this increases the signal load
+        considerably. \c timerfd()'s are delivered on a file descriptor and thus don't have such a
+        scalability issue.
+
+        \warning The timer source must not be switched from a scheduler callback
+     */
+    void hiresTimers();
+
+    /** \brief Switch back to using epoll for timing
+        \see hiresTimers()
+     */
+    void loresTimers();
+
+    /** \brief return \c true, if \c timerfd() timing is available, \c false otherwise
+        \see hiresTimers()
+     */
+    bool haveScalableHiresTimers();
+
+    /** \brief Return \c true, if using hires times, \c false otherwise
+        \see hiresTimers() */
+    bool usingHiresTimers();
+
     /** \brief Restart scheduler
         
         This call will restart all scheduler dispatchers (timers, signals, file descriptors). This
@@ -238,7 +274,7 @@ namespace scheduler {
      */
     void restart(); 
 
-    /** \brief Return \c true, if any event is registered, \c false otherwise. */
+    /** \brief Return \c true, if no event is registered, \c false otherwise. */
     bool empty();
 
     /** \brief %scheduler specific time source for Utils/Logger framework
@@ -259,6 +295,44 @@ namespace scheduler {
         senf::log::time_type operator()() const;
     };
 
+    /** \brief Temporarily block all signals
+
+        This class is used to temporarily block all signals in a critical section.
+        
+        \code
+        // Begin critical section
+        {
+            senf::scheduler::BlockSignals signalBlocker;
+
+            // critical code executed with all signals blocked
+        }
+        // End critical section
+        \endcode
+
+        You need to take care not to block since even the watchdog timer will be disabled while
+        executing within a critical section.
+     */
+    class BlockSignals
+        : boost::noncopyable
+    {
+    public:
+        BlockSignals(bool initiallyBlocked=true);
+                                        ///< Block signals until end of scope
+                                        /**< \param[in] initiallyBlocked set to \c false to not
+                                             automatically block signals initially */
+        ~BlockSignals();                ///< Release all signal blocks
+        
+        void block();                   ///< Block signals if not blocked
+        void unblock();                 ///< Unblock signals if blocked
+        bool blocked() const;           ///< \c true, if signals currently blocked, \c false
+                                        ///< otherwise
+
+    private:
+        bool blocked_;
+        sigset_t allSigs_;
+        sigset_t savedSigs_;
+    };
+
 }}
 
 ///////////////////////////////hh.e////////////////////////////////////////