1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
4 # include "../config.h"
5 #endif // HAVE_CONFIG_H
11 #ifdef HAVE_SYS_SELECT_H
12 # include <sys/select.h>
15 # include <sys/types.h>
17 # endif // HAVE_UNISTD_H
18 #endif // HAVE_SYS_SELECT_H
23 timeval Timer::_nearest_timeout, Timer::_now;
24 Timer::TimerQ Timer::_q;
26 void Timer::timevalAdd(timeval &a, long msec)
28 a.tv_sec += msec / 1000;
29 a.tv_usec += (msec % 1000) * 1000;
30 a.tv_sec += a.tv_usec / 1000000;
34 bool Timer::nearestTimeout(struct timeval &tm)
38 tm.tv_sec = _nearest_timeout.tv_sec - _now.tv_sec;
39 tm.tv_usec = _nearest_timeout.tv_usec - _now.tv_usec;
41 while (tm.tv_usec < 0) {
42 tm.tv_usec += 1000000;
45 tm.tv_sec += tm.tv_usec / 1000000;
46 tm.tv_usec %= 1000000;
53 void Timer::dispatchTimers(bool wait)
60 gettimeofday(&_now, NULL);
61 _nearest_timeout = _now;
62 _nearest_timeout.tv_sec += 10000;
66 /* since we overload the destructor to keep from removing from the middle
67 of the priority queue, set _del_me, we have to do our real delete in
76 // the queue is sorted, so if this timer shouldn't fire, none are ready
77 _nearest_timeout = curr->_timeout;
78 if (!timercmp(&_now, &_nearest_timeout, >))
81 /* we set the last fired time to delay msec after the previous firing, then
82 re-insert. timers maintain their order and may trigger more than once
83 if they've waited more than one delay's worth of time.
86 timevalAdd(curr->_last, curr->_delay);
87 curr->_action(curr->_data);
88 timevalAdd(curr->_timeout, curr->_delay);
91 /* if at least one timer fires, then don't wait on X events, as there may
92 already be some in the queue from the timer callbacks.
98 // wait for the nearest trigger, or for X to do something interesting
99 fd = ConnectionNumber(**display);
102 if (nearestTimeout(next)) {
103 select(fd + 1, &selset, NULL, NULL, &next);
105 select(fd + 1, &selset, NULL, NULL, NULL);
109 Timer::Timer(long delay, Timer::TimeoutHandler action, void *data)
117 timevalAdd(_timeout, delay);
121 void Timer::operator delete(void *self)
128 void Timer::realDelete(Timer *me)
133 void Timer::initialize(void)
135 gettimeofday(&_now, NULL);
136 _nearest_timeout.tv_sec = 100000;
137 _nearest_timeout.tv_usec = 0;
140 void Timer::destroy(void)
143 realDelete(_q.top());