PageRenderTime 28ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/mordor/timer.h

http://github.com/mozy/mordor
C Header | 113 lines | 66 code | 21 blank | 26 comment | 0 complexity | f6a0ea6307a2e58a56cd0958674ba0e3 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. #ifndef __MORDOR_TIMER_H__
  2. #define __MORDOR_TIMER_H__
  3. // Copyright (c) 2009 - Mozy, Inc.
  4. #include <set>
  5. #include <vector>
  6. #include <boost/enable_shared_from_this.hpp>
  7. #include <boost/function.hpp>
  8. #include <boost/noncopyable.hpp>
  9. #include <boost/shared_ptr.hpp>
  10. #include <boost/thread/mutex.hpp>
  11. #include <boost/weak_ptr.hpp>
  12. namespace Mordor {
  13. class TimerManager;
  14. class Timer : public boost::noncopyable, public boost::enable_shared_from_this<Timer>
  15. {
  16. friend class TimerManager;
  17. public:
  18. typedef boost::shared_ptr<Timer> ptr;
  19. private:
  20. Timer(unsigned long long us, boost::function<void ()> dg,
  21. bool recurring, TimerManager *manager);
  22. // Constructor for dummy object
  23. Timer(unsigned long long next);
  24. public:
  25. /// @return If the timer was successfully cancelled before it fired
  26. /// (if non-recurring)
  27. bool cancel();
  28. /// Refresh the timer from now
  29. /// @return If it was refreshed before firing
  30. bool refresh();
  31. /// Reset the timer to the new delay
  32. /// @param us The delay
  33. /// @param fromNow If us should be relative to now, or the original
  34. /// starting point
  35. /// @return If it was reset before firing
  36. bool reset(unsigned long long us, bool fromNow);
  37. private:
  38. bool m_recurring;
  39. unsigned long long m_next;
  40. unsigned long long m_us;
  41. boost::function<void ()> m_dg;
  42. TimerManager *m_manager;
  43. private:
  44. struct Comparator
  45. {
  46. bool operator()(const Timer::ptr &lhs, const Timer::ptr &rhs) const;
  47. };
  48. };
  49. class TimerManager : public boost::noncopyable
  50. {
  51. friend class Timer;
  52. public:
  53. TimerManager();
  54. virtual ~TimerManager();
  55. virtual Timer::ptr registerTimer(unsigned long long us,
  56. boost::function<void ()> dg, bool recurring = false);
  57. /// Conditionally execute the dg callback function only when weakCond is
  58. /// still in valid status, which means, the original object managed by the
  59. /// shared_ptr is not destroyed
  60. /// NOTE: this interface can't be called in class constructor while passing
  61. /// a shared_ptr/weak_ptr of itself.
  62. Timer::ptr registerConditionTimer(unsigned long long us,
  63. boost::function<void ()> dg,
  64. boost::weak_ptr<void> weakCond,
  65. bool recurring = false);
  66. /// @return How long until the next timer expires; ~0ull if no timers
  67. unsigned long long nextTimer();
  68. void executeTimers();
  69. /// @return Monotonically increasing count of microseconds. The number
  70. /// returned isn't guaranteed to be relative to any particular start time,
  71. /// however, the difference between two successive calls to now() is
  72. /// equal to the time that elapsed between calls. This is true even if the
  73. /// system clock is changed.
  74. static unsigned long long now();
  75. /// replace the built-in clock
  76. /// @param dg replacement function whose value will be returned by now()
  77. /// omit the parameter to return to the default clock.
  78. /// NOTE: as now() is static, this affects *all* TimerManager instances
  79. static void setClock(boost::function<unsigned long long()> dg = NULL);
  80. protected:
  81. virtual void onTimerInsertedAtFront() {}
  82. std::vector<boost::function<void ()> > processTimers();
  83. private:
  84. static boost::function<unsigned long long ()> ms_clockDg;
  85. bool detectClockRollover(unsigned long long nowUs);
  86. std::set<Timer::ptr, Timer::Comparator> m_timers;
  87. boost::mutex m_mutex;
  88. bool m_tickled;
  89. unsigned long long m_previousTime;
  90. };
  91. }
  92. #endif