X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Ftimer.cc;h=856ac8f7141fa2a1f3e844da8879d60ddf2296a1;hb=373de009f7e98b0c6f3a78f31c1e5c120cd722ed;hp=c785b3456759e3132b10321efcd3cfa101dad584;hpb=86bef745b9e974f664752c6cc56f7e6ec5642efc;p=chaz%2Fopenbox diff --git a/src/timer.cc b/src/timer.cc index c785b345..856ac8f7 100644 --- a/src/timer.cc +++ b/src/timer.cc @@ -4,65 +4,67 @@ # include "../config.h" #endif // HAVE_CONFIG_H -#include "basedisplay.hh" +#include "otk/display.hh" +#include "openbox.hh" #include "timer.hh" #include "util.hh" -BTimer::BTimer(TimerQueueManager *m, TimeoutHandler *h) { - manager = m; +namespace ob { + +OBTimer::OBTimer(TimeoutHandler *h) { handler = h; recur = timing = False; } -BTimer::~BTimer(void) { +OBTimer::~OBTimer(void) { if (timing) stop(); } -void BTimer::setTimeout(long t) { +void OBTimer::setTimeout(long t) { _timeout.tv_sec = t / 1000; _timeout.tv_usec = t % 1000; _timeout.tv_usec *= 1000; } -void BTimer::setTimeout(const timeval &t) { +void OBTimer::setTimeout(const timeval &t) { _timeout.tv_sec = t.tv_sec; _timeout.tv_usec = t.tv_usec; } -void BTimer::start(void) { +void OBTimer::start(void) { gettimeofday(&_start, 0); if (! timing) { timing = True; - manager->addTimer(this); + Openbox::instance->timerManager()->addTimer(this); } } -void BTimer::stop(void) { +void OBTimer::stop(void) { timing = False; - manager->removeTimer(this); + Openbox::instance->timerManager()->removeTimer(this); } -void BTimer::halt(void) { +void OBTimer::halt(void) { timing = False; } -void BTimer::fireTimeout(void) { +void OBTimer::fireTimeout(void) { if (handler) handler->timeout(); } -timeval BTimer::timeRemaining(const timeval &tm) const { +timeval OBTimer::timeRemaining(const timeval &tm) const { timeval ret = endpoint(); ret.tv_sec -= tm.tv_sec; @@ -72,7 +74,7 @@ timeval BTimer::timeRemaining(const timeval &tm) const { } -timeval BTimer::endpoint(void) const { +timeval OBTimer::endpoint(void) const { timeval ret; ret.tv_sec = _start.tv_sec + _timeout.tv_sec; @@ -82,9 +84,67 @@ timeval BTimer::endpoint(void) const { } -bool BTimer::shouldFire(const timeval &tm) const { +bool OBTimer::shouldFire(const timeval &tm) const { timeval end = endpoint(); return ! ((tm.tv_sec < end.tv_sec) || (tm.tv_sec == end.tv_sec && tm.tv_usec < end.tv_usec)); } + + +void OBTimerQueueManager::fire() +{ + fd_set rfds; + timeval now, tm, *timeout = (timeval *) 0; + + const int xfd = ConnectionNumber(otk::OBDisplay::display); + + FD_ZERO(&rfds); + FD_SET(xfd, &rfds); // break on any x events + + if (! timerList.empty()) { + const OBTimer* const timer = timerList.top(); + + gettimeofday(&now, 0); + tm = timer->timeRemaining(now); + + timeout = &tm; + } + + select(xfd + 1, &rfds, 0, 0, timeout); + + // check for timer timeout + gettimeofday(&now, 0); + + // there is a small chance for deadlock here: + // *IF* the timer list keeps getting refreshed *AND* the time between + // timer->start() and timer->shouldFire() is within the timer's period + // then the timer will keep firing. This should be VERY near impossible. + while (! timerList.empty()) { + OBTimer *timer = timerList.top(); + if (! timer->shouldFire(now)) + break; + + timerList.pop(); + + timer->fireTimeout(); + timer->halt(); + if (timer->isRecurring()) + timer->start(); + } +} + + +void OBTimerQueueManager::addTimer(OBTimer *timer) +{ + assert(timer); + timerList.push(timer); +} + +void OBTimerQueueManager::removeTimer(OBTimer* timer) +{ + assert(timer); + timerList.release(timer); +} + +}