1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- 2 // Timer.hh for Blackbox - An X11 Window Manager 3 // Copyright (c) 2001 - 2005 Sean 'Shaleh' Perry <shaleh@debian.org> 4 // Copyright (c) 1997 - 2000, 2002 - 2005 5 // Bradley T Hughes <bhughes at trolltech.com> 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a 8 // copy of this software and associated documentation files (the "Software"), 9 // to deal in the Software without restriction, including without limitation 10 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 // and/or sell copies of the Software, and to permit persons to whom the 12 // Software is furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 // DEALINGS IN THE SOFTWARE. 24 25 #ifndef __Timer_hh 26 #define __Timer_hh 27 28 #include "Util.hh" 29 30 #include <algorithm> 31 #include <queue> 32 #include <vector> 33 34 // forward declare to avoid the header 35 struct timeval; 36 37 namespace bt { 38 39 // use a wrapper class to avoid the header as well 40 struct timeval { 41 long tv_sec; 42 long tv_usec; 43 timevalbt::timeval44 inline timeval(void) 45 : tv_sec(0l), tv_usec(0l) 46 { } timevalbt::timeval47 inline timeval(long s, long u) 48 : tv_sec(s), tv_usec(u) 49 { } 50 51 bool operator<(const timeval &); 52 timeval operator+(const timeval &); 53 timeval &operator+=(const timeval &tv); 54 timeval operator-(const timeval &); 55 timeval &operator-=(const timeval &tv); 56 57 // POSIX<->bt conversion 58 timeval(const ::timeval &); 59 timeval &operator=(const ::timeval &); 60 operator ::timeval() const; 61 }; 62 63 timeval normalizeTimeval(const timeval &tm); 64 65 // forward declaration 66 class TimerQueueManager; 67 class Timer; 68 69 class TimeoutHandler { 70 public: 71 virtual void timeout(Timer *t) = 0; 72 }; 73 74 class Timer: public NoCopy { 75 private: 76 TimerQueueManager *manager; 77 TimeoutHandler *handler; 78 bool timing, recur; 79 80 timeval _start, _timeout; 81 82 public: 83 Timer(TimerQueueManager *m, TimeoutHandler *h); 84 virtual ~Timer(void); 85 86 void fireTimeout(void); 87 isTiming(void) const88 inline bool isTiming(void) const 89 { return timing; } isRecurring(void) const90 inline bool isRecurring(void) const 91 { return recur; } 92 timeout(void) const93 inline const timeval &timeout(void) const 94 { return _timeout; } startTime(void) const95 inline const timeval &startTime(void) const 96 { return _start; } 97 98 // adjust the start time by the given offset... this is done when 99 // the clock rolls back 100 void adjustStartTime(const timeval &offset); 101 102 timeval timeRemaining(const timeval &tm) const; 103 bool shouldFire(const timeval &tm) const; 104 timeval endpoint(void) const; 105 recurring(bool b)106 inline void recurring(bool b) 107 { recur = b; } 108 109 void setTimeout(long t); 110 void setTimeout(const timeval &t); 111 112 void start(void); // manager acquires timer 113 void stop(void); // manager releases timer 114 void halt(void); // halts the timer 115 operator <(const Timer & other) const116 inline bool operator<(const Timer& other) const 117 { return shouldFire(other.endpoint()); } 118 }; 119 120 template <class _Tp, class _Sequence, class _Compare> 121 class _timer_queue: protected std::priority_queue<_Tp, _Sequence, _Compare> { 122 public: 123 typedef std::priority_queue<_Tp, _Sequence, _Compare> _Base; 124 _timer_queue(void)125 inline _timer_queue(void) 126 : _Base() 127 { } ~_timer_queue(void)128 inline ~_timer_queue(void) 129 { } 130 release(const _Tp & value)131 inline void release(const _Tp& value) { 132 _Base::c.erase(std::remove(_Base::c.begin(), _Base::c.end(), value), 133 _Base::c.end()); 134 // after removing the item we need to make the heap again 135 std::make_heap(_Base::c.begin(), _Base::c.end(), _Base::comp); 136 } empty(void) const137 inline bool empty(void) const 138 { return _Base::empty(); } size(void) const139 inline size_t size(void) const 140 { return _Base::size(); } push(const _Tp & value)141 inline void push(const _Tp& value) 142 { _Base::push(value); } pop(void)143 inline void pop(void) 144 { _Base::pop(); } top(void) const145 inline const _Tp& top(void) const 146 { return _Base::top(); } 147 private: 148 // no copying! 149 _timer_queue(const _timer_queue&); 150 _timer_queue& operator=(const _timer_queue&); 151 }; 152 153 struct TimerLessThan { operator ()bt::TimerLessThan154 inline bool operator()(const Timer* const l, const Timer* const r) const 155 { return *r < *l; } 156 }; 157 158 typedef _timer_queue<Timer*, std::vector<Timer*>, TimerLessThan> TimerQueue; 159 160 class TimerQueueManager { 161 public: 162 virtual void addTimer(Timer* timer) = 0; 163 virtual void removeTimer(Timer* timer) = 0; 164 }; 165 166 } // namespace bt 167 168 #endif // __Timer_hh 169