aboutsummaryrefslogtreecommitdiff
path: root/src/Timer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/Timer.cc')
-rw-r--r--src/Timer.cc158
1 files changed, 126 insertions, 32 deletions
diff --git a/src/Timer.cc b/src/Timer.cc
index f35f274..2c981d3 100644
--- a/src/Timer.cc
+++ b/src/Timer.cc
@@ -19,64 +19,158 @@
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE. 20// DEALINGS IN THE SOFTWARE.
21 21
22// stupid macros needed to access some functions in version 2 of the GNU C 22#include "Timer.hh"
23// library 23
24#ifndef _GNU_SOURCE 24//use GNU extensions
25# define _GNU_SOURCE 25#ifndef _GNU_SOURCE
26#define _GNU_SOURCE
26#endif // _GNU_SOURCE 27#endif // _GNU_SOURCE
27 28
28#ifdef HAVE_CONFIG_H 29#ifdef HAVE_CONFIG_H
29# include "../config.h" 30#include "../config.h"
30#endif // HAVE_CONFIG_H 31#endif // HAVE_CONFIG_H
31 32
32#include "BaseDisplay.hh" 33#include <sys/types.h>
33#include "Timer.hh" 34#include <unistd.h>
35#include <cassert>
34 36
37//static var
38BTimer::TimerList BTimer::m_timerlist;
35 39
36BTimer::BTimer(BaseDisplay *d, TimeoutHandler *h) { 40BTimer::BTimer(TimeoutHandler *h):
37 display = d; 41m_handler(h),
38 handler = h; 42m_timing(false),
39 43m_once(false) {
40 once = timing = False;
41} 44}
42 45
43 46
44BTimer::~BTimer(void) { 47BTimer::~BTimer() {
45 if (timing) stop(); 48 if (isTiming()) stop();
46} 49}
47 50
48 51
49void BTimer::setTimeout(long t) { 52void BTimer::setTimeout(long t) {
50 _timeout.tv_sec = t / 1000; 53 m_timeout.tv_sec = t / 1000;
51 _timeout.tv_usec = t; 54 m_timeout.tv_usec = t;
52 _timeout.tv_usec -= (_timeout.tv_sec * 1000); 55 m_timeout.tv_usec -= (m_timeout.tv_sec * 1000);
53 _timeout.tv_usec *= 1000; 56 m_timeout.tv_usec *= 1000;
54} 57}
55 58
56 59
57void BTimer::setTimeout(timeval t) { 60void BTimer::setTimeout(timeval t) {
58 _timeout.tv_sec = t.tv_sec; 61 m_timeout.tv_sec = t.tv_sec;
59 _timeout.tv_usec = t.tv_usec; 62 m_timeout.tv_usec = t.tv_usec;
60} 63}
61 64
62 65
63void BTimer::start(void) { 66void BTimer::start() {
64 gettimeofday(&_start, 0); 67 gettimeofday(&m_start, 0);
68
69 if (! m_timing) {
70 m_timing = true;
71 addTimer(this); //add us to the list
72 }
73}
74
65 75
66 if (! timing) { 76void BTimer::stop() {
67 timing = True; 77 m_timing = false;
68 display->addTimer(this); 78 removeTimer(this); //remove us from the list
69 }
70} 79}
71 80
72 81
73void BTimer::stop(void) { 82void BTimer::fireTimeout() {
74 timing = False; 83 if (m_handler) m_handler->timeout();
84}
75 85
76 display->removeTimer(this); 86void BTimer::updateTimers(int fd) {
87 fd_set rfds;
88 timeval now, tm, *timeout = 0;
89
90 FD_ZERO(&rfds);
91 FD_SET(fd, &rfds);
92
93 if (m_timerlist.size() > 0) {
94 gettimeofday(&now, 0);
95
96 tm.tv_sec = tm.tv_usec = 0l;
97
98 BTimer *timer = m_timerlist.front();
99
100 tm.tv_sec = timer->getStartTime().tv_sec +
101 timer->getTimeout().tv_sec - now.tv_sec;
102 tm.tv_usec = timer->getStartTime().tv_usec +
103 timer->getTimeout().tv_usec - now.tv_usec;
104
105 while (tm.tv_usec >= 1000000) {
106 tm.tv_sec++;
107 tm.tv_usec -= 1000000;
108 }
109
110 while (tm.tv_usec < 0) {
111 if (tm.tv_sec > 0) {
112 tm.tv_sec--;
113 tm.tv_usec += 1000000;
114 } else {
115 tm.tv_usec = 0;
116 break;
117 }
118 }
119
120 timeout = &tm;
121 }
122
123 select(fd + 1, &rfds, 0, 0, timeout);
124
125 // check for timer timeout
126 gettimeofday(&now, 0);
127
128 TimerList::iterator it = m_timerlist.begin();
129 //must check end ...the timer might remove
130 //it self from the list (should be fixed in the future)
131 for(; it != m_timerlist.end(); ++it) {
132 //This is to make sure we don't get an invalid iterator
133 //when we do fireTimeout
134 BTimer &t = *(*it);
135 tm.tv_sec = t.getStartTime().tv_sec +
136 t.getTimeout().tv_sec;
137 tm.tv_usec = t.getStartTime().tv_usec +
138 t.getTimeout().tv_usec;
139
140 if ((now.tv_sec < tm.tv_sec) ||
141 (now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec))
142 break;
143
144 t.fireTimeout();
145 // restart the current timer so that the start time is updated
146 if (! t.doOnce())
147 t.start();
148 else {
149 t.stop();
150 it--;
151 }
152 }
77} 153}
78 154
155void BTimer::addTimer(BTimer *timer) {
156 assert(timer);
157
158 TimerList::iterator it = m_timerlist.begin();
159 TimerList::iterator it_end = m_timerlist.end();
160 int index = 0;
161 for (; it != it_end; ++it, ++index) {
162 if (((*it)->getTimeout().tv_sec > timer->getTimeout().tv_sec) ||
163 (((*it)->getTimeout().tv_sec == timer->getTimeout().tv_sec) &&
164 ((*it)->getTimeout().tv_usec >= timer->getTimeout().tv_usec))) {
165 break;
166 }
167 }
168 m_timerlist.insert(it, timer);
169
170}
79 171
80void BTimer::fireTimeout(void) { 172void BTimer::removeTimer(BTimer *timer) {
81 if (handler) handler->timeout(); 173 assert(timer);
174 m_timerlist.remove(timer);
82} 175}
176