aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/Timer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/Timer.cc')
-rw-r--r--src/FbTk/Timer.cc62
1 files changed, 47 insertions, 15 deletions
diff --git a/src/FbTk/Timer.cc b/src/FbTk/Timer.cc
index 09bb7dd..15da0fb 100644
--- a/src/FbTk/Timer.cc
+++ b/src/FbTk/Timer.cc
@@ -48,14 +48,15 @@ namespace FbTk {
48 48
49Timer::TimerList Timer::m_timerlist; 49Timer::TimerList Timer::m_timerlist;
50 50
51Timer::Timer():m_timing(false), m_once(false) { 51Timer::Timer():m_timing(false), m_once(false), m_interval(0) {
52 52
53} 53}
54 54
55Timer::Timer(RefCount<Command> &handler): 55Timer::Timer(RefCount<Command> &handler):
56 m_handler(handler), 56 m_handler(handler),
57 m_timing(false), 57 m_timing(false),
58 m_once(false) { 58 m_once(false),
59 m_interval(0) {
59} 60}
60 61
61 62
@@ -72,7 +73,7 @@ void Timer::setTimeout(time_t t) {
72} 73}
73 74
74 75
75void Timer::setTimeout(timeval t) { 76void Timer::setTimeout(const timeval &t) {
76 m_timeout.tv_sec = t.tv_sec; 77 m_timeout.tv_sec = t.tv_sec;
77 m_timeout.tv_usec = t.tv_usec; 78 m_timeout.tv_usec = t.tv_usec;
78} 79}
@@ -85,10 +86,10 @@ void Timer::start() {
85 gettimeofday(&m_start, 0); 86 gettimeofday(&m_start, 0);
86 87
87 // only add Timers that actually DO something 88 // only add Timers that actually DO something
88 if (! m_timing && *m_handler) { 89 if ((! m_timing || m_interval != 0) && *m_handler) {
89 m_timing = true; 90 m_timing = true;
90 addTimer(this); //add us to the list 91 addTimer(this); //add us to the list
91 } 92 }
92} 93}
93 94
94 95
@@ -111,17 +112,19 @@ void Timer::updateTimers(int fd) {
111 FD_SET(fd, &rfds); 112 FD_SET(fd, &rfds);
112 113
113 114
114 if (m_timerlist.size() > 0) { 115 if (!m_timerlist.empty()) {
115 gettimeofday(&now, 0); 116 gettimeofday(&now, 0);
116 117
117 tm.tv_sec = tm.tv_usec = 0l; 118 tm.tv_sec = tm.tv_usec = 0l;
118 119
119 Timer *timer = m_timerlist.front(); 120 Timer *timer = m_timerlist.front();
120 121
121 tm.tv_sec = timer->getStartTime().tv_sec + 122 const timeval &start = timer->getStartTime();
122 timer->getTimeout().tv_sec - now.tv_sec; 123 const timeval &length = timer->getTimeout();
123 tm.tv_usec = timer->getStartTime().tv_usec + 124 tm.tv_sec = start.tv_sec +
124 timer->getTimeout().tv_usec - now.tv_usec; 125 length.tv_sec - now.tv_sec;
126 tm.tv_usec = start.tv_usec +
127 length.tv_usec - now.tv_usec;
125 128
126 while (tm.tv_usec >= 1000000) { 129 while (tm.tv_usec >= 1000000) {
127 tm.tv_sec++; 130 tm.tv_sec++;
@@ -138,10 +141,17 @@ void Timer::updateTimers(int fd) {
138 } 141 }
139 } 142 }
140 143
144 if (tm.tv_sec < 0) {
145 tm.tv_sec = 0;
146 tm.tv_usec = 0;
147 }
148
141 timeout = &tm; 149 timeout = &tm;
142 } 150 }
143 151
144 select(fd + 1, &rfds, 0, 0, timeout); 152 if (select(fd + 1, &rfds, 0, 0, timeout) != 0)
153 // didn't time out! x events pending
154 return;
145 155
146 TimerList::iterator it; 156 TimerList::iterator it;
147 157
@@ -167,10 +177,13 @@ void Timer::updateTimers(int fd) {
167 //This is to make sure we don't get an invalid iterator 177 //This is to make sure we don't get an invalid iterator
168 //when we do fireTimeout 178 //when we do fireTimeout
169 Timer &t = *(*it); 179 Timer &t = *(*it);
170 tm.tv_sec = t.getStartTime().tv_sec + 180 const timeval &start = t.getStartTime();
171 t.getTimeout().tv_sec; 181 const timeval &length = t.getTimeout();
172 tm.tv_usec = t.getStartTime().tv_usec + 182
173 t.getTimeout().tv_usec; 183 tm.tv_sec = start.tv_sec +
184 length.tv_sec;
185 tm.tv_usec = start.tv_usec +
186 length.tv_usec;
174 187
175 if (((now.tv_sec < tm.tv_sec) || 188 if (((now.tv_sec < tm.tv_sec) ||
176 (now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec))) 189 (now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec)))
@@ -179,6 +192,9 @@ void Timer::updateTimers(int fd) {
179 t.fireTimeout(); 192 t.fireTimeout();
180 // restart the current timer so that the start time is updated 193 // restart the current timer so that the start time is updated
181 if (! t.doOnce()) { 194 if (! t.doOnce()) {
195 if (t.getInterval() != 0) {
196 it = m_timerlist.erase(it);
197 }
182 t.start(); 198 t.start();
183 199
184 // Note that this mustn't be done if we're deleting the 200 // Note that this mustn't be done if we're deleting the
@@ -200,6 +216,22 @@ void Timer::updateTimers(int fd) {
200 216
201void Timer::addTimer(Timer *timer) { 217void Timer::addTimer(Timer *timer) {
202 assert(timer); 218 assert(timer);
219 int interval = timer->getInterval();
220 // interval timers have their timeout change every time they are started!
221 if (interval != 0) {
222 timeval tm;
223 tm.tv_sec = timer->getStartTime().tv_sec;
224 tm.tv_usec = timer->getStartTime().tv_usec;
225
226 // now convert to interval
227 tm.tv_sec = interval - (tm.tv_sec % interval) - 1;
228 tm.tv_usec = 1000000 - tm.tv_usec;
229 if (tm.tv_usec == 1000000) {
230 tm.tv_usec = 0;
231 tm.tv_sec += 1;
232 }
233 timer->setTimeout(tm);
234 }
203 235
204 TimerList::iterator it = m_timerlist.begin(); 236 TimerList::iterator it = m_timerlist.begin();
205 TimerList::iterator it_end = m_timerlist.end(); 237 TimerList::iterator it_end = m_timerlist.end();