news download themes documentation links










Timer.cc

00001 // Timer.cc for FbTk - Fluxbox Toolkit
00002 // Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
00003 //
00004 // Timer.cc for Blackbox - An X11 Window Manager
00005 // Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
00006 //
00007 // Permission is hereby granted, free of charge, to any person obtaining a
00008 // copy of this software and associated documentation files (the "Software"),
00009 // to deal in the Software without restriction, including without limitation
00010 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011 // and/or sell copies of the Software, and to permit persons to whom the
00012 // Software is furnished to do so, subject to the following conditions:
00013 //
00014 // The above copyright notice and this permission notice shall be included in
00015 // all copies or substantial portions of the Software.
00016 //
00017 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00022 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00023 // DEALINGS IN THE SOFTWARE.
00024 
00025 #include "Timer.hh"
00026 
00027 #include "Command.hh"
00028 
00029 //use GNU extensions
00030 #ifndef _GNU_SOURCE
00031 #define _GNU_SOURCE
00032 #endif // _GNU_SOURCE
00033 
00034 #ifdef  HAVE_CONFIG_H
00035 #include "config.h"
00036 #endif // HAVE_CONFIG_H
00037 
00038 #include <sys/time.h>
00039 #include <sys/types.h>
00040 #include <unistd.h>
00041 #include <cassert>
00042 
00043 namespace FbTk {
00044 
00045 Timer::TimerList Timer::m_timerlist;
00046 
00047 Timer::Timer():m_timing(false), m_once(false) {
00048 
00049 }
00050 
00051 Timer::Timer(RefCount<Command> &handler):
00052     m_handler(handler),
00053     m_timing(false),
00054     m_once(false) {
00055 }
00056 
00057 
00058 Timer::~Timer() {
00059     if (isTiming()) stop();
00060 }
00061 
00062 
00063 void Timer::setTimeout(time_t t) {
00064     m_timeout.tv_sec = t / 1000;
00065     m_timeout.tv_usec = t;
00066     m_timeout.tv_usec -= (m_timeout.tv_sec * 1000);
00067     m_timeout.tv_usec *= 1000;
00068 }
00069 
00070 
00071 void Timer::setTimeout(timeval t) {
00072     m_timeout.tv_sec = t.tv_sec;
00073     m_timeout.tv_usec = t.tv_usec;
00074 }
00075 
00076 void Timer::setCommand(RefCount<Command> &cmd) {
00077     m_handler = cmd;
00078 }
00079 
00080 void Timer::start() {
00081     gettimeofday(&m_start, 0);
00082 
00083     if (! m_timing) {
00084         m_timing = true;
00085         addTimer(this); //add us to the list
00086     }
00087 }
00088 
00089 
00090 void Timer::stop() {
00091     m_timing = false;
00092     removeTimer(this); //remove us from the list
00093 }
00094 
00095 
00096 void Timer::fireTimeout() {
00097     if (*m_handler)
00098         m_handler->execute();
00099 }
00100 
00101 void Timer::updateTimers(int fd) {
00102     fd_set rfds;
00103     timeval now, tm, *timeout = 0;
00104 
00105     FD_ZERO(&rfds);
00106     FD_SET(fd, &rfds);
00107 
00108     if (m_timerlist.size() > 0) {
00109         gettimeofday(&now, 0);
00110 
00111         tm.tv_sec = tm.tv_usec = 0l;
00112 
00113         Timer *timer = m_timerlist.front();
00114 
00115         tm.tv_sec = timer->getStartTime().tv_sec +
00116             timer->getTimeout().tv_sec - now.tv_sec;
00117         tm.tv_usec = timer->getStartTime().tv_usec +
00118             timer->getTimeout().tv_usec - now.tv_usec;
00119 
00120         while (tm.tv_usec >= 1000000) {
00121             tm.tv_sec++;
00122             tm.tv_usec -= 1000000;
00123         }
00124 
00125         while (tm.tv_usec < 0) {
00126             if (tm.tv_sec > 0) {
00127                 tm.tv_sec--;
00128                 tm.tv_usec += 1000000;
00129             } else {
00130                 tm.tv_usec = 0;
00131                 break;
00132             }
00133         }
00134 
00135         timeout = &tm;
00136     }
00137 
00138     select(fd + 1, &rfds, 0, 0, timeout);
00139 
00140     // check for timer timeout
00141     gettimeofday(&now, 0);
00142 
00143     TimerList::iterator it = m_timerlist.begin();
00144     //must check end ...the timer might remove
00145     //it self from the list (should be fixed in the future)
00146     for(; it != m_timerlist.end(); ++it) {
00147         //This is to make sure we don't get an invalid iterator
00148         //when we do fireTimeout
00149         Timer &t = *(*it);
00150         tm.tv_sec = t.getStartTime().tv_sec +
00151             t.getTimeout().tv_sec;
00152         tm.tv_usec = t.getStartTime().tv_usec +
00153             t.getTimeout().tv_usec;
00154 
00155         if ((now.tv_sec < tm.tv_sec) ||
00156             (now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec))
00157             break;
00158 
00159         t.fireTimeout();
00160         // restart the current timer so that the start time is updated
00161         if (! t.doOnce())
00162             t.start();
00163         else {
00164             t.stop();           
00165             it--;
00166         }                   
00167     }
00168 }
00169 
00170 void Timer::addTimer(Timer *timer) {
00171     assert(timer);
00172 
00173     TimerList::iterator it = m_timerlist.begin();
00174     TimerList::iterator it_end = m_timerlist.end();
00175     int index = 0;
00176     for (; it != it_end; ++it, ++index) {
00177         if (((*it)->getTimeout().tv_sec > timer->getTimeout().tv_sec) ||
00178             (((*it)->getTimeout().tv_sec == timer->getTimeout().tv_sec) &&
00179              ((*it)->getTimeout().tv_usec >= timer->getTimeout().tv_usec))) {
00180             break;
00181         }
00182     }
00183     m_timerlist.insert(it, timer); 
00184 
00185 }
00186 
00187 void Timer::removeTimer(Timer *timer) {
00188     assert(timer);
00189     m_timerlist.remove(timer);
00190 }
00191     
00192 }; // end namespace FbTk

Fluxbox CVS-Jan-2003




      



Got comments about the page? Send them to webmaster.
If you have general Fluxbox related questions ask them on our irc channel or mailing lists.

Show Source








Designed by aLEczapKA