This commit is contained in:
Mathias Gumz 2013-02-10 11:08:05 +01:00
parent 2e98d9ed0d
commit 34744f504e
2 changed files with 31 additions and 31 deletions

View file

@ -134,16 +134,16 @@ void Timer::start() {
void Timer::stop() { void Timer::stop() {
if (isTiming()) { s_timerlist.erase(this);
s_timerlist.erase(this);
m_start = 0;
}
} }
uint64_t Timer::getEndTime() const { uint64_t Timer::getEndTime() const {
return m_start + m_timeout; return m_start + m_timeout;
} }
int Timer::isTiming() const {
return s_timerlist.find(const_cast<FbTk::Timer*>(this)) != s_timerlist.end();
}
void Timer::fireTimeout() { void Timer::fireTimeout() {
if (m_handler) if (m_handler)
@ -153,74 +153,74 @@ void Timer::fireTimeout() {
void Timer::updateTimers(int fd) { void Timer::updateTimers(int fd) {
fd_set rfds; fd_set rfds;
timeval tm; timeval* tout;
timeval* timeout = 0; timeval tm;
TimerList::iterator it; TimerList::iterator t;
bool overdue = false;
uint64_t now;
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(fd, &rfds); FD_SET(fd, &rfds);
tout = NULL;
bool overdue = false;
uint64_t now = FbTime::mono();
uint64_t end_time;
// search for overdue timers // search for overdue timers
if (!s_timerlist.empty()) { if (!s_timerlist.empty()) {
Timer* timer = *s_timerlist.begin(); Timer* timer = *s_timerlist.begin();
end_time = timer->getEndTime(); uint64_t end_time = timer->getEndTime();
if (end_time < now) { now = FbTime::mono();
if (end_time <= now) {
overdue = true; overdue = true;
} else { } else {
uint64_t diff = (end_time - now); uint64_t diff = (end_time - now);
tm.tv_sec = diff / FbTime::IN_SECONDS; tm.tv_sec = diff / FbTime::IN_SECONDS;
tm.tv_usec = diff % FbTime::IN_SECONDS; tm.tv_usec = diff % FbTime::IN_SECONDS;
tout = &tm;
} }
timeout = &tm;
} }
// if not overdue, wait for the next xevent via the blocking // if not overdue, wait for the next xevent via the blocking
// select(), so OS sends fluxbox to sleep. the select() will // select(), so OS sends fluxbox to sleep. the select() will
// time out when the next timer has to be handled // time out when the next timer has to be handled
if (!overdue && select(fd + 1, &rfds, 0, 0, timeout) != 0) { if (!overdue && select(fd + 1, &rfds, 0, 0, tout) != 0) {
// didn't time out! x events are pending // didn't time out! x events are pending
return; return;
} }
// stoping / restarting the timers modifies the list in an upredictable // stoping / restarting the timers modifies the list in an upredictable
// way. to avoid problems such as infinite loops we save the current // way. to avoid problems (infinite loops etc) we copy the current overdue
// (ordered) list of timers into a list and work on it. // timers from the gloabl (and ordered) list of timers and work on it.
static std::vector<FbTk::Timer*> timeouts; static std::vector<FbTk::Timer*> timeouts;
now = FbTime::mono(); now = FbTime::mono();
for (it = s_timerlist.begin(); it != s_timerlist.end(); ++it ) { for (t = s_timerlist.begin(); t != s_timerlist.end(); ++t ) {
if (now < (*it)->getEndTime()) { if (now < (*t)->getEndTime()) {
break; break;
} }
timeouts.push_back(*it); timeouts.push_back(*t);
} }
size_t i; size_t i;
const size_t ts = timeouts.size(); const size_t ts = timeouts.size();
for (i = 0; i < ts; ++i) { for (i = 0; i < ts; ++i) {
FbTk::Timer& t = *timeouts[i]; FbTk::Timer& timer = *timeouts[i];
// first we stop the timer to remove it // first we stop the timer to remove it
// from s_timerlist // from s_timerlist
t.stop(); timer.stop();
// then we call the handler which might (re)start 't' // then we call the handler which might (re)start 't'
// on it's own // on it's own
t.fireTimeout(); timer.fireTimeout();
// restart 't' if needed // restart 't' if needed
if (!t.doOnce() && !t.isTiming()) { if (!timer.doOnce() && !timer.isTiming()) {
t.start(); timer.start();
} }
} }

View file

@ -61,7 +61,7 @@ public:
static void updateTimers(int file_descriptor); static void updateTimers(int file_descriptor);
int isTiming() const { return (m_start > 0); } int isTiming() const;
int getInterval() const { return m_interval; } int getInterval() const { return m_interval; }
int doOnce() const { return m_once; } int doOnce() const { return m_once; }
@ -80,7 +80,7 @@ private:
bool m_once; ///< do timeout only once? bool m_once; ///< do timeout only once?
int m_interval; ///< Is an interval-only timer (e.g. clock), in seconds int m_interval; ///< Is an interval-only timer (e.g. clock), in seconds
uint64_t m_start; ///< start time in microseconds, 0 if not running uint64_t m_start; ///< start time in microseconds
uint64_t m_timeout; ///< time length in microseconds uint64_t m_timeout; ///< time length in microseconds
}; };