PPI: Implement joins
[senf.git] / Scheduler / Scheduler.hh
index a2f96da..ba077e4 100644 (file)
@@ -33,8 +33,8 @@
 #include <boost/function.hpp>
 #include <boost/utility.hpp>
 #include <boost/call_traits.hpp>
-
-#include "Utils/MicroTime.hh"
+#include <boost/integer.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
 
 //#include "scheduler.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -45,7 +45,7 @@ namespace senf {
     /** \brief Singleton class to manage the event loop
 
         This class manages a single select() type event loop. A customer of this class may register
-        any number of file descriptiors with this class and pass callback functions to be called on
+        any number of file descriptors with this class and pass callback functions to be called on
         input, output or error. This functions are specified using boost::function objects (See <a
         href="http://www.boost.org/doc/html/function.html">Boost.Function</a>)
 
@@ -54,16 +54,16 @@ namespace senf {
         \code
           int fd = retrieve_filehandle(object);
         \endcode
-        is valid and places the relevent file descriptor into fd can be used as a Handle type. There
+        is valid and places the relevant file descriptor into fd can be used as a Handle type. There
         is an implementation of retrieve_filehandle(int) within the library to handle explicit file
-        descrptors. The <a href="../../../Socket/doc/html/index.html">Socket library</a> provides an
-        implementation of <tt>retrive_filehandle(FileHandle handle)</tt>. If you want to support
-        some other handle type, just define an apropriate \c retrieve_filehandle function <em>in
+        descriptors. The <a href="../../../Socket/doc/html/index.html">Socket library</a> provides an
+        implementation of <tt>retrieve_filehandle(FileHandle handle)</tt>. If you want to support
+        some other handle type, just define an appropriate \c retrieve_filehandle function <em>in
         that types namespace</em>.
 
         It is important to note, that for every combination of file descriptor and event, only a \e
         single handler may be installed. Installing more handlers does not make sense. If you need
-        to distribute data to serveral interested parties, you must take care of this yourself.
+        to distribute data to several interested parties, you must take care of this yourself.
 
         \todo Fix EventId parameter (probably to int) to allow |-ing without casting ...
       */
@@ -74,10 +74,11 @@ namespace senf {
         ///////////////////////////////////////////////////////////////////////////
         // Types
 
-        /// \brief Types of file descriptor events */
+        /** \brief Types of file descriptor events */
         enum EventId { EV_NONE=0,
-                       EV_READ=1, EV_PRIO=2, EV_WRITE=4, EV_HUP=8, EV_ERR=16,
-                       EV_ALL=31 };
+                       EV_READ=1, EV_PRIO=2, EV_WRITE=4, 
+                       EV_ALL=7,
+                       EV_HUP=8, EV_ERR=16 };
 
         /** \brief Template typedef for Callback type
 
@@ -91,6 +92,20 @@ namespace senf {
             typedef boost::function<void (typename boost::call_traits<Handle>::param_type,
                                           EventId) > Callback;
         };
+
+        /** \brief Scheduler time data type
+            
+            Unsigned integer type representing scheduler time. Scheduler time is measured in
+            nanoseconds relative to some implementation defined reference time.
+         */
+        typedef boost::uint_fast64_t sched_time;
+
+        /** \brief Absolute time data type
+
+            Boost.DateTime datatype used to represent absolute date/time values.
+         */
+        typedef boost::posix_time::ptime abs_time;
+
         /** \brief Callback type for timer events */
         typedef boost::function<void ()> TimerCallback;
 
@@ -111,7 +126,7 @@ namespace senf {
             time
 
             \implementation This static member just defines the Scheduler as a static method
-                variable. The C++ standard then provides above guaratee. The instance will be
+                variable. The C++ standard then provides above guarantee. The instance will be
                 initialized the first time, the code flow passes the variable declaration found in
                 the instance() body.
          */
@@ -125,10 +140,10 @@ namespace senf {
                  typename GenericCallback<Handle>::Callback const & cb,
                  int eventMask = EV_ALL); ///< Add file handle event callback
                                         /**< add() will add a callback to the Scheduler. The
-                                             callbeck will be called for the given type of event on
+                                             callback will be called for the given type of event on
                                              the given  arbitrary file-descriptor or
                                              handle-like object. If there already is a Callback
-                                             register ed for one of the events requested, the new
+                                             registered for one of the events requested, the new
                                              handler will replace the old one.
                                              \param[in] handle file descriptor or handle providing
                                                  the Handle interface defined above.
@@ -145,8 +160,8 @@ namespace senf {
                                              \param[in] eventMask arbitrary combination via '|'
                                                  operator of EventId designators. */
 
-        void timeout(unsigned long timeout, TimerCallback const & cb); ///< Add timeout event
-                                        /**< \param[in] timeout timeout in milliseconds
+        void timeout(sched_time timeout, TimerCallback const & cb); ///< Add timeout event
+                                        /**< \param[in] timeout timeout in nanoseconds
                                              \param[in] cb callback to call after \a timeout
                                                  milliseconds
                                              \todo Return some kind of handle/pointer and add
@@ -162,12 +177,34 @@ namespace senf {
                                              main loop to terminate. The main loop will return to
                                              it's caller after the currently running callback
                                              returns. */
+        
+        abs_time abstime(sched_time time) const; ///< Convert scheduler time to absolute time
+                                        /**< This member converts a scheduler time value into an
+                                             absolute Boost.DateTime value. 
+                                             \note You should not base timeout calculations on this
+                                                 absolute time value. Scheduler time is guaranteed
+                                                 to be monotonous, absolute time may be
+                                                 non-monotonous if the system date/time is
+                                                 changed. */
+
+        sched_time schedtime(abs_time time) const; ///< Convert absolute time to scheduler time
+                                        /**< This member converst an absolute time value into the
+                                             corresponding scheduler time.
+                                             \see abstime */
+
+        sched_time now() const;         ///< Return current date/time
+                                        /**< The return value represents the current date/time in
+                                             scheduler time representation */
+
+        sched_time eventTime() const;   ///< Return date/time of last event
 
     protected:
 
     private:
         typedef boost::function<void (EventId)> SimpleCallback;
 
+        static unsigned const MinTimeout = 1000;
+
         Scheduler();
 
         void do_add(int fd, SimpleCallback const & cb, int eventMask = EV_ALL);
@@ -180,8 +217,6 @@ namespace senf {
             SimpleCallback cb_read;
             SimpleCallback cb_prio;
             SimpleCallback cb_write;
-            SimpleCallback cb_hup;
-            SimpleCallback cb_err;
 
             int epollMask() const;
         };
@@ -191,13 +226,13 @@ namespace senf {
         struct TimerSpec
         {
             TimerSpec() : timeout(), cb() {}
-            TimerSpec(unsigned long long timeout_, TimerCallback cb_)
+            TimerSpec(sched_time timeout_, TimerCallback cb_)
                 : timeout(timeout_), cb(cb_) {}
 
             bool operator< (TimerSpec const & other) const
                 { return timeout > other.timeout; }
 
-            unsigned long long timeout;
+            sched_time timeout;
             TimerCallback cb;
         };
 
@@ -208,6 +243,7 @@ namespace senf {
         TimerQueue timerQueue_;
         int epollFd_;
         bool terminate_;
+        abs_time epoch_;
     };
 
     /** \brief Default file descriptor accessor
@@ -234,4 +270,6 @@ namespace senf {
 // c-file-style: "senf"
 // indent-tabs-mode: nil
 // ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
 // End: