00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "Timer.hh"
00026
00027 #include "Command.hh"
00028
00029
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);
00086 }
00087 }
00088
00089
00090 void Timer::stop() {
00091 m_timing = false;
00092 removeTimer(this);
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
00141 gettimeofday(&now, 0);
00142
00143 TimerList::iterator it = m_timerlist.begin();
00144
00145
00146 for(; it != m_timerlist.end(); ++it) {
00147
00148
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
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 };