Scheduler/TimerEventProxy: added timeout() member
tho [Wed, 14 Apr 2010 11:43:38 +0000 (11:43 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1595 270642c3-0616-0410-b53a-bc976706d245

senf/Scheduler/ClockService.hh
senf/Scheduler/ClockService.test.cc
senf/Scheduler/TimerEventProxy.ct
senf/Scheduler/TimerEventProxy.hh
senf/Scheduler/TimerEventProxy.test.cc

index 0dde5c7..3bb09f9 100644 (file)
@@ -46,7 +46,7 @@ namespace senf {
 #endif
 
     // Implementation note: The clock value is represented as a 64bit unsigned integer number of
-    // nanosecods based on the CLOCK_MONOTONIC POSIX clock.
+    // nanoseconds based on the CLOCK_MONOTONIC POSIX clock.
     //
     // To allow conversion between clock value and absolute time, the ClockService samples the
     // absolute current time and the clock value when the conversion is performed. This is done at
@@ -59,7 +59,7 @@ namespace senf {
 
         \implementation The funny mixture of static and non-static members stems from the old
             implementation based on interval timers and gettimeofday(). The current implementation
-            usses POSIX clocks and is much simpler and more precise.
+            uses POSIX clocks and is much simpler and more precise.
       */
     class ClockService
         : singleton<ClockService>
@@ -112,7 +112,7 @@ namespace senf {
                                                  than the clock_type resolution */
 
         static clock_type clock(abstime_type time); ///< Convert absolute time to clock value
-                                        /**< This member converst an absolute time value into the
+                                        /**< This member convert an absolute time value into the
                                              corresponding clock value.
                                              \see abstime */
 
@@ -142,7 +142,7 @@ namespace senf {
         static int64_type in_hours(clock_type v); ///< Convert \a v to hours
         static int64_type in_days(clock_type v); ///< Convert \a v to days
 
-        static void restart(); ///< Force re-syncronisation of abstime and clock
+        static void restart(); ///< Force re-synchronization of abstime and clock
                                         /**< Calling the member should never be necessary since
                                              abstime() / clock() automatically call restart() if
                                              needed */
index e6d405a..d634c05 100644 (file)
@@ -56,6 +56,8 @@ namespace {
 
 SENF_AUTO_UNIT_TEST(clockService)
 {
+    BOOST_CHECK( senf::ClockService::abstime(0).is_not_a_date_time());
+    
     char const * enabled (getenv("SENF_TIMING_CRITICAL_TESTS"));
     BOOST_WARN_MESSAGE(enabled, "Set SENF_TIMING_CRITICAL_TESTS to not skip timing critical tests");
     BOOST_CHECK( true );
index 32098e2..0c1899d 100644 (file)
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
- \brief TimerEventProxy public header */
+    \brief TimerEventProxy non-inline template implementation */
 
-#define prefix_ 
+// Custom includes
 
-template<class T>
-prefix_ senf::scheduler::TimerEventProxy<T>::TimerEventProxy() 
-    : timer("TimerEventProxy", senf::membind(&TimerEventProxy<T>::timerEvent, this), 0, false), 
-      entrySetById(entrySet.template get<Id> ()),
-      entrySetByTimeout(entrySet.template get<Timeout> ())
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template<typename IdType>
+prefix_ senf::scheduler::TimerEventProxy<IdType>::TimerEventProxy() 
+    : entrySetById( entrySet.template get<Id>()),
+      entrySetByTimeout( entrySet.template get<Timeout> ()),
+      timer( "TimerEventProxy", membind(&TimerEventProxy<IdType>::timerEvent, this), 0, false)
 { }
 
-template<class T>
-prefix_ senf::scheduler::TimerEventProxy<T>::TimerEventProxy( std::string const & name,
-        senf::console::DirectoryNode & node) 
-    : timer("TimerEventProxy", senf::membind(&TimerEventProxy<T>::timerEvent, this), 0, false),
-      entrySetById(entrySet.template get<Id> ()),
-      entrySetByTimeout(entrySet.template get<Timeout> ())
+template<typename IdType>
+prefix_ senf::scheduler::TimerEventProxy<IdType>::TimerEventProxy(std::string const & name, console::DirectoryNode & node) 
+    : entrySetById( entrySet.template get<Id>()),
+      entrySetByTimeout( entrySet.template get<Timeout> ()),
+      timer( "TimerEventProxy", membind(&TimerEventProxy<IdType>::timerEvent, this), 0, false)
 {
-    node.add(name, senf::console::factory::Command(
-            &TimerEventProxy<T>::list, this) .doc("List active Timers"));
+    node.add(name, console::factory::Command(
+            &TimerEventProxy<IdType>::list, this) .doc("List active Timers"));
 }
 
-template<class T>
-prefix_ void senf::scheduler::TimerEventProxy<T>::timerEvent() {
-
-    senf::ClockService::clock_type actual = senf::ClockService::now();
-    typename EntrySetByTimeout_t::iterator it;
-
-    // execute the timer callbacks first
-
-    it = entrySetByTimeout.begin();
+template<typename IdType>
+prefix_ void senf::scheduler::TimerEventProxy<IdType>::timerEvent()
+{
+    ClockService::clock_type actual = ClockService::now();
+    typename EntrySetByTimeout_t::iterator it = entrySetByTimeout.begin();
     while (it != entrySetByTimeout.end() && it->timeout <= actual) {
         Entry item (*it);
         // remove due entry from set
         entrySetByTimeout.erase(it);
         // call callback
         item.cb(actual, item.id);
-
         it = entrySetByTimeout.begin();
     }
-
-    if (entrySet.size() > 0) {
+    if (entrySet.size() > 0)
         timer.timeout(entrySetByTimeout.begin()->timeout);
-    }
 }
 
-template<class IdType>
+template<typename IdType>
 prefix_ void senf::scheduler::TimerEventProxy<IdType>::add(
-        senf::ClockService::clock_type timeout, IdType const & id, Callback cb)
+        ClockService::clock_type timeout, IdType const & id, Callback cb)
 {
     // insert new entry
     entrySetByTimeout.insert( Entry(timeout, id, cb));
-
     // the scheduler time to the first earliest timeout (ordered index)
     timer.timeout( entrySetByTimeout.begin()->timeout);
 }
 
-template<class IdType>
+template<typename IdType>
 prefix_ bool senf::scheduler::TimerEventProxy<IdType>::remove(IdType const & id)
 {
     return entrySetById.erase( id) > 0;
 }
 
-template<class IdType>
+template<typename IdType>
+prefix_ senf::ClockService::clock_type senf::scheduler::TimerEventProxy<IdType>::timeout(IdType const & id)
+    const
+{
+    typename EntrySetById_t::const_iterator i ( entrySetById.find( id));
+    return i == entrySetById.end() ? 0 : i->timeout;
+}
+
+
+template<typename IdType>
 prefix_ std::vector<std::pair<senf::ClockService::clock_type, IdType> > senf::scheduler::TimerEventProxy<IdType>::list()
+    const
 {
-    std::vector<std::pair<senf::ClockService::clock_type, IdType> > tmp;
+    std::vector<std::pair<ClockService::clock_type, IdType> > tmp;
 
-    typename EntrySetByTimeout_t::iterator it;
+    typename EntrySetByTimeout_t::const_iterator it;
     for (it = entrySetByTimeout.begin(); it != entrySetByTimeout.end(); ++it) {
-        tmp.push_back(std::make_pair<senf::ClockService::clock_type, IdType>( it->timeout, it->id));
+        tmp.push_back(std::make_pair<ClockService::clock_type, IdType>( it->timeout, it->id));
     }
-
     return tmp;
 }
 
+///////////////////////////////ct.e////////////////////////////////////////
 #undef prefix_
 
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
+// End:
+
+
index cea7f03..08301ec 100644 (file)
 #ifndef HH_SENF_Scheduler_TimerEventProxy_
 #define HH_SENF_Scheduler_TimerEventProxy_ 1
 
-#ifdef SENF_DEBUG
-#   define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
-#   define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
-#endif
-
-#include <boost/range/iterator_range.hpp>
+// Custom includes
 #include <boost/multi_index_container.hpp>
 #include <boost/multi_index/ordered_index.hpp>
 #include <boost/multi_index/member.hpp>
@@ -41,6 +36,7 @@
 #include <senf/Scheduler/TimerEvent.hh>
 #include <senf/Utils/Console/Console.hh>
 
+///////////////////////////////hh.p////////////////////////////////////////
 namespace senf {
 namespace scheduler {
 
@@ -57,48 +53,44 @@ namespace scheduler {
     class TimerEventProxy 
     {
     public:
-        ///////////////////////////////////////////////////////////////////////////
-        // Types
-        typedef boost::function<void(senf::ClockService::clock_type, IdType const &)> Callback;
-
-        TimerEventProxy();
-        ///< Instantiate a TimerEventProxy
-
-        TimerEventProxy(std::string const & name, senf::console::DirectoryNode & node);
-        ///< Instantiate a TimerEventProxy and add the list command to the give DirectoryNode
+        typedef boost::function<void(ClockService::clock_type, IdType const &)> Callback;
 
-        void add(senf::ClockService::clock_type timeout, IdType const &id, Callback cb);
-        ///< Add new deadline timer
-        bool remove(IdType const & id);
-        ///< Remove timer by given \a id.
-        std::vector<std::pair<senf::ClockService::clock_type, IdType> > list();
-        ///< Returns a vector of all active timers with timeout and id.
+        TimerEventProxy();              ///< Instantiate a TimerEventProxy
+        TimerEventProxy(std::string const & name, console::DirectoryNode & node);
+                                        /**< \brief Instantiate a TimerEventProxy and add the list
+                                                    command to the give DirectoryNode */
         
+        void add(ClockService::clock_type timeout, IdType const & id, Callback cb);
+                                        ///< Add new deadline timer
+        
+        bool remove(IdType const & id); ///< Remove timer by given \a id.
+        
+        std::vector<std::pair<ClockService::clock_type, IdType> > list() const;
+                                        ///< Returns a vector of all active timers with timeout and id.
+        
+        ClockService::clock_type timeout(IdType const & id) const;
+                                        ///< Returns timeout for given id
+                                        /**< if no timer for this id is registered \a 0 is returned. */ 
     private:
 #ifndef DOXYGEN
         struct Entry {
-            senf::ClockService::clock_type timeout;
+            ClockService::clock_type timeout;
             IdType id;
             Callback cb;
 
-            Entry(senf::ClockService::clock_type _timeout, IdType _id, Callback _cb)
+            Entry(ClockService::clock_type _timeout, IdType _id, Callback _cb)
                 : timeout(_timeout), id(_id), cb(_cb) { }
         };
-
-        senf::scheduler::TimerEvent timer;
-
-        //
-        // data structure to hold active timers
-        //
         struct Timeout {};
         struct Id {};
 #endif
+        // data structure to hold active timers
         typedef boost::multi_index_container<
             Entry,
             boost::multi_index::indexed_by<
                 boost::multi_index::ordered_non_unique<
                     boost::multi_index::tag<Timeout>,
-                    boost::multi_index::member<Entry, senf::ClockService::clock_type, &Entry::timeout> 
+                    boost::multi_index::member<Entry, ClockService::clock_type, &Entry::timeout> 
                 >,
                 boost::multi_index::ordered_unique<
                     boost::multi_index::tag<Id>,
@@ -106,20 +98,33 @@ namespace scheduler {
                 >
             >
         > EntrySet_t;
-
         typedef typename EntrySet_t::template index<Timeout>::type EntrySetByTimeout_t;
         typedef typename EntrySet_t::template index<Id>::type EntrySetById_t;
 
         EntrySet_t entrySet;
         EntrySetById_t & entrySetById;
         EntrySetByTimeout_t & entrySetByTimeout;
+        
+        scheduler::TimerEvent timer;
 
-        // callback for the Scheduler timer event
-        void timerEvent();
+        void timerEvent();  // callback for the Scheduler timer event
     };
-}
-}
 
-#include "TimerEventProxy.ct"
+}}
 
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "TimerEventProxy.cci"
+#include "TimerEventProxy.ct"
+//#include "TimerEventProxy.cti"
 #endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
index e682687..a4ce7ed 100644 (file)
@@ -67,12 +67,19 @@ SENF_AUTO_UNIT_TEST(timerEventProxy)
         timers.add( t + senf::ClockService::milliseconds(800), 4, &handler);
         timers.add( t + senf::ClockService::milliseconds(200), 1, &handler);
         BOOST_CHECK( timers.remove( 4));
+        BOOST_CHECK(! timers.remove( 4));
         timers.add( t + senf::ClockService::milliseconds(700), 2, &handler);
+        
+        BOOST_CHECK_EQUAL( timers.timeout(1), t + senf::ClockService::milliseconds(200));
+        BOOST_CHECK_EQUAL( timers.timeout(2), t + senf::ClockService::milliseconds(700));
+        BOOST_CHECK_EQUAL( timers.timeout(4), 0);
 
         run( senf::ClockService::milliseconds( 1000));
 
         BOOST_CHECK( mask == 3);
     }
+    
+    senf::scheduler::TimerEventProxy<int> timers ("test", senf::console::ScopedDirectory<>());
 }