aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/Timer.cc
diff options
context:
space:
mode:
authorfluxgen <fluxgen>2003-01-09 21:09:49 (GMT)
committerfluxgen <fluxgen>2003-01-09 21:09:49 (GMT)
commit7dd4823340ae5f710a08ff3a8fbe4276defc6b85 (patch)
treef4b6623ecf435a643fcf247d3075aaf79d6e82f3 /src/FbTk/Timer.cc
parent7a74a56fe48b319fecf56cede8e16f9c03dfaa96 (diff)
downloadfluxbox-7dd4823340ae5f710a08ff3a8fbe4276defc6b85.zip
fluxbox-7dd4823340ae5f710a08ff3a8fbe4276defc6b85.tar.bz2
moved from fluxbox to fbtk
Diffstat (limited to 'src/FbTk/Timer.cc')
-rw-r--r--src/FbTk/Timer.cc182
1 files changed, 182 insertions, 0 deletions
diff --git a/src/FbTk/Timer.cc b/src/FbTk/Timer.cc
new file mode 100644
index 0000000..4305658
--- /dev/null
+++ b/src/FbTk/Timer.cc
@@ -0,0 +1,182 @@
1// Timer.cc for FbTk - Fluxbox Toolkit
2// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
3//
4// Timer.cc for Blackbox - An X11 Window Manager
5// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
6//
7// Permission is hereby granted, free of charge, to any person obtaining a
8// copy of this software and associated documentation files (the "Software"),
9// to deal in the Software without restriction, including without limitation
10// the rights to use, copy, modify, merge, publish, distribute, sublicense,
11// and/or sell copies of the Software, and to permit persons to whom the
12// Software is furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE.
24
25#include "Timer.hh"
26
27//use GNU extensions
28#ifndef _GNU_SOURCE
29#define _GNU_SOURCE
30#endif // _GNU_SOURCE
31
32#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif // HAVE_CONFIG_H
35
36#include <sys/time.h>
37#include <sys/types.h>
38#include <unistd.h>
39#include <cassert>
40
41namespace FbTk {
42
43Timer::TimerList Timer::m_timerlist;
44
45Timer::Timer(TimeoutHandler *h):
46 m_handler(h),
47 m_timing(false),
48 m_once(false) {
49}
50
51
52Timer::~Timer() {
53 if (isTiming()) stop();
54}
55
56
57void Timer::setTimeout(long t) {
58 m_timeout.tv_sec = t / 1000;
59 m_timeout.tv_usec = t;
60 m_timeout.tv_usec -= (m_timeout.tv_sec * 1000);
61 m_timeout.tv_usec *= 1000;
62}
63
64
65void Timer::setTimeout(timeval t) {
66 m_timeout.tv_sec = t.tv_sec;
67 m_timeout.tv_usec = t.tv_usec;
68}
69
70
71void Timer::start() {
72 gettimeofday(&m_start, 0);
73
74 if (! m_timing) {
75 m_timing = true;
76 addTimer(this); //add us to the list
77 }
78}
79
80
81void Timer::stop() {
82 m_timing = false;
83 removeTimer(this); //remove us from the list
84}
85
86
87void Timer::fireTimeout() {
88 if (m_handler) m_handler->timeout();
89}
90
91void Timer::updateTimers(int fd) {
92 fd_set rfds;
93 timeval now, tm, *timeout = 0;
94
95 FD_ZERO(&rfds);
96 FD_SET(fd, &rfds);
97
98 if (m_timerlist.size() > 0) {
99 gettimeofday(&now, 0);
100
101 tm.tv_sec = tm.tv_usec = 0l;
102
103 Timer *timer = m_timerlist.front();
104
105 tm.tv_sec = timer->getStartTime().tv_sec +
106 timer->getTimeout().tv_sec - now.tv_sec;
107 tm.tv_usec = timer->getStartTime().tv_usec +
108 timer->getTimeout().tv_usec - now.tv_usec;
109
110 while (tm.tv_usec >= 1000000) {
111 tm.tv_sec++;
112 tm.tv_usec -= 1000000;
113 }
114
115 while (tm.tv_usec < 0) {
116 if (tm.tv_sec > 0) {
117 tm.tv_sec--;
118 tm.tv_usec += 1000000;
119 } else {
120 tm.tv_usec = 0;
121 break;
122 }
123 }
124
125 timeout = &tm;
126 }
127
128 select(fd + 1, &rfds, 0, 0, timeout);
129
130 // check for timer timeout
131 gettimeofday(&now, 0);
132
133 TimerList::iterator it = m_timerlist.begin();
134 //must check end ...the timer might remove
135 //it self from the list (should be fixed in the future)
136 for(; it != m_timerlist.end(); ++it) {
137 //This is to make sure we don't get an invalid iterator
138 //when we do fireTimeout
139 Timer &t = *(*it);
140 tm.tv_sec = t.getStartTime().tv_sec +
141 t.getTimeout().tv_sec;
142 tm.tv_usec = t.getStartTime().tv_usec +
143 t.getTimeout().tv_usec;
144
145 if ((now.tv_sec < tm.tv_sec) ||
146 (now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec))
147 break;
148
149 t.fireTimeout();
150 // restart the current timer so that the start time is updated
151 if (! t.doOnce())
152 t.start();
153 else {
154 t.stop();
155 it--;
156 }
157 }
158}
159
160void Timer::addTimer(Timer *timer) {
161 assert(timer);
162
163 TimerList::iterator it = m_timerlist.begin();
164 TimerList::iterator it_end = m_timerlist.end();
165 int index = 0;
166 for (; it != it_end; ++it, ++index) {
167 if (((*it)->getTimeout().tv_sec > timer->getTimeout().tv_sec) ||
168 (((*it)->getTimeout().tv_sec == timer->getTimeout().tv_sec) &&
169 ((*it)->getTimeout().tv_usec >= timer->getTimeout().tv_usec))) {
170 break;
171 }
172 }
173 m_timerlist.insert(it, timer);
174
175}
176
177void Timer::removeTimer(Timer *timer) {
178 assert(timer);
179 m_timerlist.remove(timer);
180}
181
182}; // end namespace FbTk