From: tho Date: Wed, 14 Apr 2010 11:43:38 +0000 (+0000) Subject: Scheduler/TimerEventProxy: added timeout() member X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=4adca0eda1b26c8ca84421fd936f8450713ca6fd;p=senf.git Scheduler/TimerEventProxy: added timeout() member git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1595 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Scheduler/ClockService.hh b/senf/Scheduler/ClockService.hh index 0dde5c7..3bb09f9 100644 --- a/senf/Scheduler/ClockService.hh +++ b/senf/Scheduler/ClockService.hh @@ -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 @@ -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 */ diff --git a/senf/Scheduler/ClockService.test.cc b/senf/Scheduler/ClockService.test.cc index e6d405a..d634c05 100644 --- a/senf/Scheduler/ClockService.test.cc +++ b/senf/Scheduler/ClockService.test.cc @@ -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 ); diff --git a/senf/Scheduler/TimerEventProxy.ct b/senf/Scheduler/TimerEventProxy.ct index 32098e2..0c1899d 100644 --- a/senf/Scheduler/TimerEventProxy.ct +++ b/senf/Scheduler/TimerEventProxy.ct @@ -22,81 +22,97 @@ // 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 -prefix_ senf::scheduler::TimerEventProxy::TimerEventProxy() - : timer("TimerEventProxy", senf::membind(&TimerEventProxy::timerEvent, this), 0, false), - entrySetById(entrySet.template get ()), - entrySetByTimeout(entrySet.template get ()) +#define prefix_ +///////////////////////////////ct.p//////////////////////////////////////// + +template +prefix_ senf::scheduler::TimerEventProxy::TimerEventProxy() + : entrySetById( entrySet.template get()), + entrySetByTimeout( entrySet.template get ()), + timer( "TimerEventProxy", membind(&TimerEventProxy::timerEvent, this), 0, false) { } -template -prefix_ senf::scheduler::TimerEventProxy::TimerEventProxy( std::string const & name, - senf::console::DirectoryNode & node) - : timer("TimerEventProxy", senf::membind(&TimerEventProxy::timerEvent, this), 0, false), - entrySetById(entrySet.template get ()), - entrySetByTimeout(entrySet.template get ()) +template +prefix_ senf::scheduler::TimerEventProxy::TimerEventProxy(std::string const & name, console::DirectoryNode & node) + : entrySetById( entrySet.template get()), + entrySetByTimeout( entrySet.template get ()), + timer( "TimerEventProxy", membind(&TimerEventProxy::timerEvent, this), 0, false) { - node.add(name, senf::console::factory::Command( - &TimerEventProxy::list, this) .doc("List active Timers")); + node.add(name, console::factory::Command( + &TimerEventProxy::list, this) .doc("List active Timers")); } -template -prefix_ void senf::scheduler::TimerEventProxy::timerEvent() { - - senf::ClockService::clock_type actual = senf::ClockService::now(); - typename EntrySetByTimeout_t::iterator it; - - // execute the timer callbacks first - - it = entrySetByTimeout.begin(); +template +prefix_ void senf::scheduler::TimerEventProxy::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 +template prefix_ void senf::scheduler::TimerEventProxy::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 +template prefix_ bool senf::scheduler::TimerEventProxy::remove(IdType const & id) { return entrySetById.erase( id) > 0; } -template +template +prefix_ senf::ClockService::clock_type senf::scheduler::TimerEventProxy::timeout(IdType const & id) + const +{ + typename EntrySetById_t::const_iterator i ( entrySetById.find( id)); + return i == entrySetById.end() ? 0 : i->timeout; +} + + +template prefix_ std::vector > senf::scheduler::TimerEventProxy::list() + const { - std::vector > tmp; + std::vector > 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( it->timeout, it->id)); + tmp.push_back(std::make_pair( it->timeout, it->id)); } - return tmp; } +///////////////////////////////ct.e//////////////////////////////////////// #undef prefix_ + +// 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: + + diff --git a/senf/Scheduler/TimerEventProxy.hh b/senf/Scheduler/TimerEventProxy.hh index cea7f03..08301ec 100644 --- a/senf/Scheduler/TimerEventProxy.hh +++ b/senf/Scheduler/TimerEventProxy.hh @@ -27,12 +27,7 @@ #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 +// Custom includes #include #include #include @@ -41,6 +36,7 @@ #include #include +///////////////////////////////hh.p//////////////////////////////////////// namespace senf { namespace scheduler { @@ -57,48 +53,44 @@ namespace scheduler { class TimerEventProxy { public: - /////////////////////////////////////////////////////////////////////////// - // Types - typedef boost::function 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 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 > 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 > 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, - boost::multi_index::member + boost::multi_index::member >, boost::multi_index::ordered_unique< boost::multi_index::tag, @@ -106,20 +98,33 @@ namespace scheduler { > > > EntrySet_t; - typedef typename EntrySet_t::template index::type EntrySetByTimeout_t; typedef typename EntrySet_t::template index::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 + + +// 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: diff --git a/senf/Scheduler/TimerEventProxy.test.cc b/senf/Scheduler/TimerEventProxy.test.cc index e682687..a4ce7ed 100644 --- a/senf/Scheduler/TimerEventProxy.test.cc +++ b/senf/Scheduler/TimerEventProxy.test.cc @@ -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 timers ("test", senf::console::ScopedDirectory<>()); }