aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/FbTk/Timer.cc58
-rw-r--r--src/FbTk/Timer.hh4
2 files changed, 31 insertions, 31 deletions
diff --git a/src/FbTk/Timer.cc b/src/FbTk/Timer.cc
index 422e9c6..387c5d2 100644
--- a/src/FbTk/Timer.cc
+++ b/src/FbTk/Timer.cc
@@ -134,16 +134,16 @@ void Timer::start() {
134 134
135 135
136void Timer::stop() { 136void Timer::stop() {
137 if (isTiming()) { 137 s_timerlist.erase(this);
138 s_timerlist.erase(this);
139 m_start = 0;
140 }
141} 138}
142 139
143uint64_t Timer::getEndTime() const { 140uint64_t Timer::getEndTime() const {
144 return m_start + m_timeout; 141 return m_start + m_timeout;
145} 142}
146 143
144int Timer::isTiming() const {
145 return s_timerlist.find(const_cast<FbTk::Timer*>(this)) != s_timerlist.end();
146}
147 147
148void Timer::fireTimeout() { 148void Timer::fireTimeout() {
149 if (m_handler) 149 if (m_handler)
@@ -153,74 +153,74 @@ void Timer::fireTimeout() {
153 153
154void Timer::updateTimers(int fd) { 154void Timer::updateTimers(int fd) {
155 155
156 fd_set rfds; 156 fd_set rfds;
157 timeval tm; 157 timeval* tout;
158 timeval* timeout = 0; 158 timeval tm;
159 TimerList::iterator it; 159 TimerList::iterator t;
160 bool overdue = false;
161 uint64_t now;
162
160 163
161 FD_ZERO(&rfds); 164 FD_ZERO(&rfds);
162 FD_SET(fd, &rfds); 165 FD_SET(fd, &rfds);
163 166 tout = NULL;
164 bool overdue = false;
165 uint64_t now = FbTime::mono();
166 uint64_t end_time;
167 167
168 // search for overdue timers 168 // search for overdue timers
169 if (!s_timerlist.empty()) { 169 if (!s_timerlist.empty()) {
170 170
171 Timer* timer = *s_timerlist.begin(); 171 Timer* timer = *s_timerlist.begin();
172 end_time = timer->getEndTime(); 172 uint64_t end_time = timer->getEndTime();
173 173
174 if (end_time < now) { 174 now = FbTime::mono();
175 if (end_time <= now) {
175 overdue = true; 176 overdue = true;
176 } else { 177 } else {
177 uint64_t diff = (end_time - now); 178 uint64_t diff = (end_time - now);
178 tm.tv_sec = diff / FbTime::IN_SECONDS; 179 tm.tv_sec = diff / FbTime::IN_SECONDS;
179 tm.tv_usec = diff % FbTime::IN_SECONDS; 180 tm.tv_usec = diff % FbTime::IN_SECONDS;
181 tout = &tm;
180 } 182 }
181
182 timeout = &tm;
183 } 183 }
184 184
185 // if not overdue, wait for the next xevent via the blocking 185 // if not overdue, wait for the next xevent via the blocking
186 // select(), so OS sends fluxbox to sleep. the select() will 186 // select(), so OS sends fluxbox to sleep. the select() will
187 // time out when the next timer has to be handled 187 // time out when the next timer has to be handled
188 if (!overdue && select(fd + 1, &rfds, 0, 0, timeout) != 0) { 188 if (!overdue && select(fd + 1, &rfds, 0, 0, tout) != 0) {
189 // didn't time out! x events are pending 189 // didn't time out! x events are pending
190 return; 190 return;
191 } 191 }
192 192
193 // stoping / restarting the timers modifies the list in an upredictable 193 // stoping / restarting the timers modifies the list in an upredictable
194 // way. to avoid problems such as infinite loops we save the current 194 // way. to avoid problems (infinite loops etc) we copy the current overdue
195 // (ordered) list of timers into a list and work on it. 195 // timers from the gloabl (and ordered) list of timers and work on it.
196 196
197 static std::vector<FbTk::Timer*> timeouts; 197 static std::vector<FbTk::Timer*> timeouts;
198 198
199 now = FbTime::mono(); 199 now = FbTime::mono();
200 for (it = s_timerlist.begin(); it != s_timerlist.end(); ++it ) { 200 for (t = s_timerlist.begin(); t != s_timerlist.end(); ++t ) {
201 if (now < (*it)->getEndTime()) { 201 if (now < (*t)->getEndTime()) {
202 break; 202 break;
203 } 203 }
204 timeouts.push_back(*it); 204 timeouts.push_back(*t);
205 } 205 }
206 206
207 size_t i; 207 size_t i;
208 const size_t ts = timeouts.size(); 208 const size_t ts = timeouts.size();
209 for (i = 0; i < ts; ++i) { 209 for (i = 0; i < ts; ++i) {
210 210
211 FbTk::Timer& t = *timeouts[i]; 211 FbTk::Timer& timer = *timeouts[i];
212 212
213 // first we stop the timer to remove it 213 // first we stop the timer to remove it
214 // from s_timerlist 214 // from s_timerlist
215 t.stop(); 215 timer.stop();
216 216
217 // then we call the handler which might (re)start 't' 217 // then we call the handler which might (re)start 't'
218 // on it's own 218 // on it's own
219 t.fireTimeout(); 219 timer.fireTimeout();
220 220
221 // restart 't' if needed 221 // restart 't' if needed
222 if (!t.doOnce() && !t.isTiming()) { 222 if (!timer.doOnce() && !timer.isTiming()) {
223 t.start(); 223 timer.start();
224 } 224 }
225 } 225 }
226 226
diff --git a/src/FbTk/Timer.hh b/src/FbTk/Timer.hh
index 2e82f2a..b4ce55e 100644
--- a/src/FbTk/Timer.hh
+++ b/src/FbTk/Timer.hh
@@ -61,7 +61,7 @@ public:
61 61
62 static void updateTimers(int file_descriptor); 62 static void updateTimers(int file_descriptor);
63 63
64 int isTiming() const { return (m_start > 0); } 64 int isTiming() const;
65 int getInterval() const { return m_interval; } 65 int getInterval() const { return m_interval; }
66 66
67 int doOnce() const { return m_once; } 67 int doOnce() const { return m_once; }
@@ -80,7 +80,7 @@ private:
80 bool m_once; ///< do timeout only once? 80 bool m_once; ///< do timeout only once?
81 int m_interval; ///< Is an interval-only timer (e.g. clock), in seconds 81 int m_interval; ///< Is an interval-only timer (e.g. clock), in seconds
82 82
83 uint64_t m_start; ///< start time in microseconds, 0 if not running 83 uint64_t m_start; ///< start time in microseconds
84 uint64_t m_timeout; ///< time length in microseconds 84 uint64_t m_timeout; ///< time length in microseconds
85}; 85};
86 86