# DBus-C++

## Desktop Communication Bus System

libdbus-c-- Documentation 0.9.0

- Files
- Data Structures
- Globals
- Main Page

eventloop.cpp
Go to the documentation of this file.
1/*
2 *
3 * D-Bus++ - C++ bindings for D-Bus
4 *
5 * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com>
6 *
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27
28#include <dbus-c++/eventloop.h>
29#include <dbus-c++/debug.h>
30
31#include <sys/poll.h>
32#include <sys/time.h>
33
34#include <dbus/dbus.h>
35
36 using namespace DBus;
37 using namespace std;
38
39 static double millis(timeval tv)
40{
41 return (tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0);
42}
43
44 DefaultTimeout::DefaultTimeout(int interval, bool repeat, DefaultMainLoop *ed)
45 : _enabled(true), _interval(interval), _repeat(repeat), _expiration(0), _data(0), _disp(ed)
46{
47 timeval now;
48 gettimeofday(&now, NULL);
49
50 _expiration = millis(now) + interval;
51
52 _disp->_mutex_t.lock();
53 _disp->_timeouts.push_back(this);
54 _disp->_mutex_t.unlock();
55}
56
57 DefaultTimeout::~DefaultTimeout()
58{
59 _disp->_mutex_t.lock();
60 _disp->_timeouts.remove(this);
61 _disp->_mutex_t.unlock();
62}
63
64 DefaultWatch::DefaultWatch(int fd, int flags, DefaultMainLoop *ed)
65 : _enabled(true), _fd(fd), _flags(flags), _state(0), _data(0), _disp(ed)
66{
67 _disp->_mutex_w.lock();
68 _disp->_watches.push_back(this);
69 _disp->_mutex_w.unlock();
70}
71
72 DefaultWatch::~DefaultWatch()
73{
74 _disp->_mutex_w.lock();
75 _disp->_watches.remove(this);
76 _disp->_mutex_w.unlock();
77}
78
79 DefaultMutex::DefaultMutex()
80{
81 pthread_mutex_init(&_mutex, NULL);
82}
83
84 DefaultMutex::DefaultMutex(bool recursive)
85{
86 if (recursive)
87 {
88 pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
89 _mutex = recmutex;
90 }
91 else
92 {
93 pthread_mutex_init(&_mutex, NULL);
94 }
95}
96
97 DefaultMutex::~DefaultMutex()
98{
99 pthread_mutex_destroy(&_mutex);
100}
101
102 void DefaultMutex::lock()
103{
104 pthread_mutex_lock(&_mutex);
105}
106
107 void DefaultMutex::unlock()
108{
109 pthread_mutex_unlock(&_mutex);
110}
111
112 DefaultMainLoop::DefaultMainLoop() :
113 _mutex_t(true),
114 _mutex_w(true)
115{
116}
117
118 DefaultMainLoop::~DefaultMainLoop()
119{
120 _mutex_w.lock();
121
122 DefaultWatches::iterator wi = _watches.begin();
123 while (wi != _watches.end())
124 {
125 DefaultWatches::iterator wmp = wi;
126 ++wmp;
127 _mutex_w.unlock();
128 delete(*wi);
129 _mutex_w.lock();
130 wi = wmp;
131 }
132 _mutex_w.unlock();
133
134 _mutex_t.lock();
135
136 DefaultTimeouts::iterator ti = _timeouts.begin();
137 while (ti != _timeouts.end())
138 {
139 DefaultTimeouts::iterator tmp = ti;
140 ++tmp;
141 _mutex_t.unlock();
142 delete(*ti);
143 _mutex_t.lock();
144 ti = tmp;
145 }
146 _mutex_t.unlock();
147}
148
149 void DefaultMainLoop::dispatch()
150{
151 _mutex_w.lock();
152
153 int nfd = _watches.size();
154
155 if (_fdunlock)
156 {
157 nfd = nfd + 2;
158 }
159
160 pollfd fds[nfd];
161
162 DefaultWatches::iterator wi = _watches.begin();
163
164 for (nfd = 0; wi != _watches.end(); ++wi)
165 {
166 if ((*wi)->enabled())
167 {
168 fds[nfd].fd = (*wi)->descriptor();
169 fds[nfd].events = (*wi)->flags();
170 fds[nfd].revents = 0;
171
172 ++nfd;
173 }
174 }
175
176 if (_fdunlock)
177 {
178 fds[nfd].fd = _fdunlock[0];
179 fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
180 fds[nfd].revents = 0;
181
182 nfd++;
183 fds[nfd].fd = _fdunlock[1];
184 fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
185 fds[nfd].revents = 0;
186 }
187
188 _mutex_w.unlock();
189
190 int wait_min = 10000;
191
192 DefaultTimeouts::iterator ti;
193
194 _mutex_t.lock();
195
196 for (ti = _timeouts.begin(); ti != _timeouts.end(); ++ti)
197 {
198 if ((*ti)->enabled() && (*ti)->interval() < wait_min)
199 wait_min = (*ti)->interval();
200 }
201
202 _mutex_t.unlock();
203
204 poll(fds, nfd, wait_min);
205
206 timeval now;
207 gettimeofday(&now, NULL);
208
209 double now_millis = millis(now);
210
211 _mutex_t.lock();
212
213 ti = _timeouts.begin();
214
215 while (ti != _timeouts.end())
216 {
217 DefaultTimeouts::iterator tmp = ti;
218 ++tmp;
219
220 if ((*ti)->enabled() && now_millis >= (*ti)->_expiration)
221 {
222 (*ti)->expired(*(*ti));
223
224 if ((*ti)->_repeat)
225 {
226 (*ti)->_expiration = now_millis + (*ti)->_interval;
227 }
228
229 }
230
231 ti = tmp;
232 }
233
234 _mutex_t.unlock();
235
236 _mutex_w.lock();
237
238 for (int j = 0; j < nfd; ++j)
239 {
240 DefaultWatches::iterator wi;
241
242 for (wi = _watches.begin(); wi != _watches.end();)
243 {
244 DefaultWatches::iterator tmp = wi;
245 ++tmp;
246
247 if ((*wi)->enabled() && (*wi)->_fd == fds[j].fd)
248 {
249 if (fds[j].revents)
250 {
251 (*wi)->_state = fds[j].revents;
252
253 (*wi)->ready(*(*wi));
254
255 fds[j].revents = 0;
256 }
257 }
258
259 wi = tmp;
260 }
261 }
262 _mutex_w.unlock();
263}
264
DBus::DefaultMainLoop::_fdunlock
int _fdunlock[2]
Definition eventloop.h:210
DBus::DefaultMainLoop::_timeouts
DefaultTimeouts _timeouts
Definition eventloop.h:214
DBus::DefaultMainLoop::dispatch
virtual void dispatch()
Definition eventloop.cpp:149
DBus::DefaultMainLoop::_mutex_t
DefaultMutex _mutex_t
Definition eventloop.h:213
DBus::DefaultMainLoop::_mutex_w
DefaultMutex _mutex_w
Definition eventloop.h:216
DBus::DefaultMainLoop::_watches
DefaultWatches _watches
Definition eventloop.h:217
DBus::DefaultMainLoop::DefaultMainLoop
DefaultMainLoop()
Definition eventloop.cpp:112
DBus::DefaultMainLoop::~DefaultMainLoop
virtual ~DefaultMainLoop()
Definition eventloop.cpp:118
DBus::DefaultMutex::lock
void lock()
Definition eventloop.cpp:102
DBus::DefaultMutex::unlock
void unlock()
Definition eventloop.cpp:107
DBus::DefaultMutex::~DefaultMutex
~DefaultMutex()
Definition eventloop.cpp:97
DBus::DefaultMutex::_mutex
pthread_mutex_t _mutex
Definition eventloop.h:197
DBus::DefaultMutex::DefaultMutex
DefaultMutex()
Definition eventloop.cpp:79
DBus::DefaultTimeout::DefaultMainLoop
friend class DefaultMainLoop
Definition eventloop.h:105
DBus::DefaultTimeout::_expiration
double _expiration
Definition eventloop.h:99
DBus::DefaultTimeout::~DefaultTimeout
virtual ~DefaultTimeout()
Definition eventloop.cpp:57
DBus::DefaultTimeout::_repeat
bool _repeat
Definition eventloop.h:97
DBus::DefaultTimeout::_disp
DefaultMainLoop * _disp
Definition eventloop.h:103
DBus::DefaultTimeout::_enabled
bool _enabled
Definition eventloop.h:94
DBus::DefaultTimeout::DefaultTimeout
DefaultTimeout(int interval, bool repeat, DefaultMainLoop *)
Definition eventloop.cpp:44
DBus::DefaultTimeout::_data
void * _data
Definition eventloop.h:101
DBus::DefaultTimeout::interval
int interval()
Definition eventloop.h:63
DBus::DefaultTimeout::repeat
bool repeat()
Definition eventloop.h:72
DBus::DefaultTimeout::_interval
int _interval
Definition eventloop.h:96
DBus::DefaultWatch::DefaultMainLoop
friend class DefaultMainLoop
Definition eventloop.h:169
DBus::DefaultWatch::_disp
DefaultMainLoop * _disp
Definition eventloop.h:167
DBus::DefaultWatch::_state
int _state
Definition eventloop.h:163
DBus::DefaultWatch::_data
void * _data
Definition eventloop.h:165
DBus::DefaultWatch::_enabled
bool _enabled
Definition eventloop.h:159
DBus::DefaultWatch::_fd
int _fd
Definition eventloop.h:161
DBus::DefaultWatch::DefaultWatch
DefaultWatch(int fd, int flags, DefaultMainLoop *)
Definition eventloop.cpp:64
DBus::DefaultWatch::~DefaultWatch
virtual ~DefaultWatch()
Definition eventloop.cpp:72
DBus::DefaultWatch::flags
int flags()
Definition eventloop.h:132
DBus::DefaultWatch::_flags
int _flags
Definition eventloop.h:162
debug.h
millis
static double millis(timeval tv)
Definition eventloop.cpp:39
eventloop.h
DBus
Definition connection_p.h:42