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