# DBus-C++

## Desktop Communication Bus System

libdbus-c-- Documentation 0.9.0

- Files
- Data Structures
- Globals
- Main Page

dispatcher.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++/dispatcher.h>
29
30#include <dbus/dbus.h>
31
32#include "dispatcher_p.h"
33#include "server_p.h"
34#include "connection_p.h"
35
36 DBus::Dispatcher *DBus::default_dispatcher = NULL;
37
38 using namespace DBus;
39
40 Timeout::Timeout(Timeout::Internal *i)
41 : _int(i)
42{
43 dbus_timeout_set_data((DBusTimeout *)i, this, NULL);
44}
45
46 int Timeout::interval() const
47{
48 return dbus_timeout_get_interval((DBusTimeout *)_int);
49}
50
51 bool Timeout::enabled() const
52{
53 return dbus_timeout_get_enabled((DBusTimeout *)_int);
54}
55
56 bool Timeout::handle()
57{
58 return dbus_timeout_handle((DBusTimeout *)_int);
59}
60
61/*
62*/
63
64 Watch::Watch(Watch::Internal *i)
65 : _int(i)
66{
67 dbus_watch_set_data((DBusWatch *)i, this, NULL);
68}
69
70 int Watch::descriptor() const
71{
72#if HAVE_WIN32
73 return dbus_watch_get_socket((DBusWatch *)_int);
74#else
75 // check dbus version and use dbus_watch_get_unix_fd() only in dbus >= 1.1.1
76#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || \
77 (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MAJOR > 1) || \
78 (DBUS_VERSION_MAJOR > 1)
79 return dbus_watch_get_unix_fd((DBusWatch *)_int);
80#else
81 return dbus_watch_get_fd((DBusWatch *)_int);
82#endif
83#endif
84}
85
86 int Watch::flags() const
87{
88 return dbus_watch_get_flags((DBusWatch *)_int);
89}
90
91 bool Watch::enabled() const
92{
93 return dbus_watch_get_enabled((DBusWatch *)_int);
94}
95
96 bool Watch::handle(int flags)
97{
98 return dbus_watch_handle((DBusWatch *)_int, flags);
99}
100
101/*
102*/
103
104dbus_bool_t Dispatcher::Private::on_add_watch(DBusWatch *watch, void *data)
105{
106 Dispatcher *d = static_cast<Dispatcher *>(data);
107
108 Watch::Internal *w = reinterpret_cast<Watch::Internal *>(watch);
109
110 d->add_watch(w);
111
112 return true;
113}
114
115 void Dispatcher::Private::on_rem_watch(DBusWatch *watch, void *data)
116{
117 Dispatcher *d = static_cast<Dispatcher *>(data);
118
119 Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
120
121 d->rem_watch(w);
122}
123
124 void Dispatcher::Private::on_toggle_watch(DBusWatch *watch, void *data)
125{
126 Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
127
128 w->toggle();
129}
130
131dbus_bool_t Dispatcher::Private::on_add_timeout(DBusTimeout *timeout, void *data)
132{
133 Dispatcher *d = static_cast<Dispatcher *>(data);
134
135 Timeout::Internal *t = reinterpret_cast<Timeout::Internal *>(timeout);
136
137 d->add_timeout(t);
138
139 return true;
140}
141
142 void Dispatcher::Private::on_rem_timeout(DBusTimeout *timeout, void *data)
143{
144 Dispatcher *d = static_cast<Dispatcher *>(data);
145
146 Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
147
148 d->rem_timeout(t);
149}
150
151 void Dispatcher::Private::on_toggle_timeout(DBusTimeout *timeout, void *data)
152{
153 Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
154
155 t->toggle();
156}
157
158 void Dispatcher::queue_connection(Connection::Private *cp)
159{
160 _mutex_p.lock();
161 _pending_queue.push_back(cp);
162 _mutex_p.unlock();
163}
164
165
166 bool Dispatcher::has_something_to_dispatch()
167{
168 _mutex_p.lock();
169 bool has_something = false;
170 for (Connection::PrivatePList::iterator it = _pending_queue.begin();
171 it != _pending_queue.end() && !has_something;
172 ++it)
173 {
174 has_something = (*it)->has_something_to_dispatch();
175 }
176
177 _mutex_p.unlock();
178 return has_something;
179}
180
181
182 void Dispatcher::dispatch_pending()
183{
184 while (1)
185 {
186 _mutex_p.lock();
187 if (_pending_queue.empty())
188 {
189 _mutex_p.unlock();
190 break;
191 }
192
193 Connection::PrivatePList pending_queue_copy(_pending_queue);
194 _mutex_p.unlock();
195
196 size_t copy_elem_num(pending_queue_copy.size());
197
198 dispatch_pending(pending_queue_copy);
199
200 //only push_back on list is mandatory!
201 _mutex_p.lock();
202
203 Connection::PrivatePList::iterator i, j;
204 i = _pending_queue.begin();
205 size_t counter = 0;
206 while (counter < copy_elem_num && i != _pending_queue.end())
207 {
208 j = i;
209 ++j;
210 _pending_queue.erase(i);
211 i = j;
212 ++counter;
213 }
214
215 _mutex_p.unlock();
216 }
217}
218
219 void Dispatcher::dispatch_pending(Connection::PrivatePList &pending_queue)
220{
221 // SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things...
222
223 _mutex_p_copy.lock();
224 while (pending_queue.size() > 0)
225 {
226 Connection::PrivatePList::iterator i, j;
227
228 i = pending_queue.begin();
229
230 while (i != pending_queue.end())
231 {
232 j = i;
233
234 ++j;
235
236 if ((*i)->do_dispatch())
237 pending_queue.erase(i);
238 else
239 debug_log("dispatch_pending_private: do_dispatch error");
240
241 i = j;
242 }
243 }
244 _mutex_p_copy.unlock();
245}
246
247 void DBus::_init_threading()
248{
249#ifdef DBUS_HAS_THREADS_INIT_DEFAULT
250 dbus_threads_init_default();
251#else
252 debug_log("Thread support is not enabled! Your D-Bus version is too old!");
253#endif//DBUS_HAS_THREADS_INIT_DEFAULT
254}
255
256 void DBus::_init_threading(
257 MutexNewFn m1,
258 MutexFreeFn m2,
259 MutexLockFn m3,
260 MutexUnlockFn m4,
261 CondVarNewFn c1,
262 CondVarFreeFn c2,
263 CondVarWaitFn c3,
264 CondVarWaitTimeoutFn c4,
265 CondVarWakeOneFn c5,
266 CondVarWakeAllFn c6
267)
268{
269#ifndef DBUS_HAS_RECURSIVE_MUTEX
270 DBusThreadFunctions functions =
271 {
272 DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK |
273 DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK |
274 DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK |
275 DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK |
276 DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
277 DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
278 DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
279 DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
280 DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK |
281 DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
282 (DBusMutexNewFunction) m1,
283 (DBusMutexFreeFunction) m2,
284 (DBusMutexLockFunction) m3,
285 (DBusMutexUnlockFunction) m4,
286 (DBusCondVarNewFunction) c1,
287 (DBusCondVarFreeFunction) c2,
288 (DBusCondVarWaitFunction) c3,
289 (DBusCondVarWaitTimeoutFunction) c4,
290 (DBusCondVarWakeOneFunction) c5,
291 (DBusCondVarWakeAllFunction) c6
292 };
293#else
294 DBusThreadFunctions functions =
295 {
296 DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK |
297 DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK |
298 DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK |
299 DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK |
300 DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
301 DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
302 DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
303 DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
304 DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK |
305 DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
306 0, 0, 0, 0,
307 (DBusCondVarNewFunction) c1,
308 (DBusCondVarFreeFunction) c2,
309 (DBusCondVarWaitFunction) c3,
310 (DBusCondVarWaitTimeoutFunction) c4,
311 (DBusCondVarWakeOneFunction) c5,
312 (DBusCondVarWakeAllFunction) c6,
313 (DBusRecursiveMutexNewFunction) m1,
314 (DBusRecursiveMutexFreeFunction) m2,
315 (DBusRecursiveMutexLockFunction) m3,
316 (DBusRecursiveMutexUnlockFunction) m4
317 };
318#endif//DBUS_HAS_RECURSIVE_MUTEX
319 dbus_threads_init(&functions);
320}
DBus::Connection::PrivatePList
std::list< Private * > PrivatePList
Definition connection.h:60
DBus::Dispatcher
Definition dispatcher.h:152
DBus::Dispatcher::add_watch
virtual Watch * add_watch(Watch::Internal *)=0
DBus::Dispatcher::_mutex_p_copy
DefaultMutex _mutex_p_copy
Definition dispatcher.h:181
DBus::Dispatcher::add_timeout
virtual Timeout * add_timeout(Timeout::Internal *)=0
DBus::Dispatcher::rem_timeout
virtual void rem_timeout(Timeout *)=0
DBus::Dispatcher::queue_connection
void queue_connection(Connection::Private *)
Definition dispatcher.cpp:158
DBus::Dispatcher::_mutex_p
DefaultMutex _mutex_p
Definition dispatcher.h:180
DBus::Dispatcher::rem_watch
virtual void rem_watch(Watch *)=0
DBus::Dispatcher::dispatch_pending
void dispatch_pending()
Definition dispatcher.cpp:182
DBus::Dispatcher::has_something_to_dispatch
bool has_something_to_dispatch()
Definition dispatcher.cpp:166
DBus::Dispatcher::_pending_queue
Connection::PrivatePList _pending_queue
Definition dispatcher.h:183
DBus::Timeout
Definition dispatcher.h:36
DBus::Timeout::toggle
virtual void toggle()=0
DBus::Timeout::enabled
bool enabled() const
Definition dispatcher.cpp:51
DBus::Timeout::interval
int interval() const
Gets the timeout interval.
Definition dispatcher.cpp:46
DBus::Timeout::handle
bool handle()
Calls the timeout handler for this timeout.
Definition dispatcher.cpp:56
DBus::Timeout::Timeout
Timeout(Internal *i)
DBus::Timeout::_int
Internal * _int
Definition dispatcher.h:83
DBus::Watch
Definition dispatcher.h:87
DBus::Watch::enabled
bool enabled() const
Definition dispatcher.cpp:91
DBus::Watch::flags
int flags() const
Gets flags from DBusWatchFlags indicating what conditions should be monitored on the file descriptor.
Definition dispatcher.cpp:86
DBus::Watch::Watch
Watch(Internal *i)
DBus::Watch::handle
bool handle(int flags)
Called to notify the D-Bus library when a previously-added watch is ready for reading or writing,...
Definition dispatcher.cpp:96
DBus::Watch::toggle
virtual void toggle()=0
DBus::Watch::_int
Internal * _int
Definition dispatcher.h:148
DBus::Watch::descriptor
int descriptor() const
A main loop could poll this descriptor to integrate dbus-c++.
Definition dispatcher.cpp:70
connection_p.h
dispatcher.h
dispatcher_p.h
DBus
Definition connection_p.h:42
DBus::CondVarFreeFn
void(* CondVarFreeFn)(CondVar *cv)
Definition dispatcher.h:241
DBus::_init_threading
void DXXAPI _init_threading()
Definition dispatcher.cpp:247
DBus::CondVarNewFn
CondVar *(* CondVarNewFn)()
Definition dispatcher.h:240
DBus::CondVarWaitTimeoutFn
bool(* CondVarWaitTimeoutFn)(CondVar *cv, Mutex *mx, int timeout)
Definition dispatcher.h:243
DBus::default_dispatcher
DXXAPI Dispatcher * default_dispatcher
Definition dispatcher.cpp:36
DBus::MutexUnlockFn
void(* MutexUnlockFn)(Mutex *mx)
Definition dispatcher.h:230
DBus::MutexLockFn
bool(* MutexLockFn)(Mutex *mx)
Definition dispatcher.h:234
DBus::CondVarWakeAllFn
void(* CondVarWakeAllFn)(CondVar *cv)
Definition dispatcher.h:245
DBus::MutexNewFn
Mutex *(* MutexNewFn)()
Definition dispatcher.h:229
DBus::CondVarWakeOneFn
void(* CondVarWakeOneFn)(CondVar *cv)
Definition dispatcher.h:244
DBus::CondVarWaitFn
void(* CondVarWaitFn)(CondVar *cv, Mutex *mx)
Definition dispatcher.h:242
DBus::debug_log
DXXAPI LogFunction debug_log
Definition debug.cpp:55
DBus::MutexFreeFn
bool(* MutexFreeFn)(Mutex *mx)
Definition dispatcher.h:233
server_p.h
DBus::Connection::Private
Definition connection_p.h:45
DBus::Dispatcher::Private::on_rem_watch
static void on_rem_watch(DBusWatch *watch, void *data)
Definition dispatcher.cpp:115
DBus::Dispatcher::Private::on_add_timeout
static dbus_bool_t on_add_timeout(DBusTimeout *timeout, void *data)
Definition dispatcher.cpp:131
DBus::Dispatcher::Private::on_add_watch
static dbus_bool_t on_add_watch(DBusWatch *watch, void *data)
Definition dispatcher.cpp:104
DBus::Dispatcher::Private::on_toggle_timeout
static void on_toggle_timeout(DBusTimeout *timeout, void *data)
Definition dispatcher.cpp:151
DBus::Dispatcher::Private::on_toggle_watch
static void on_toggle_watch(DBusWatch *watch, void *data)
Definition dispatcher.cpp:124
DBus::Dispatcher::Private::on_rem_timeout
static void on_rem_timeout(DBusTimeout *timeout, void *data)
Definition dispatcher.cpp:142