# DBus-C++

## Desktop Communication Bus System

libdbus-c-- Documentation 0.9.0

- Files
- Data Structures
- Globals
- Main Page

eventloop-integration.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/* Project */
29#include <dbus-c++/eventloop-integration.h>
30#include <dbus-c++/debug.h>
31#include <dbus-c++/pipe.h>
32
33/* DBus */
34#include <dbus/dbus.h>
35
36/* STD */
37#include <unistd.h>
38#include <string.h>
39#include <cassert>
40#include <sys/poll.h>
41#include <fcntl.h>
42
43 using namespace DBus;
44 using namespace std;
45
46 BusTimeout::BusTimeout(Timeout::Internal *ti, BusDispatcher *bd)
47 : Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd)
48{
49 DefaultTimeout::enabled(Timeout::enabled());
50}
51
52 void BusTimeout::toggle()
53{
54 debug_log("timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");
55
56 DefaultTimeout::enabled(Timeout::enabled());
57}
58
59 BusWatch::BusWatch(Watch::Internal *wi, BusDispatcher *bd)
60 : Watch(wi), DefaultWatch(Watch::descriptor(), 0, bd)
61{
62 int flags = POLLHUP | POLLERR;
63
64 if (Watch::flags() & DBUS_WATCH_READABLE)
65 flags |= POLLIN;
66 if (Watch::flags() & DBUS_WATCH_WRITABLE)
67 flags |= POLLOUT;
68
69 DefaultWatch::flags(flags);
70 DefaultWatch::enabled(Watch::enabled());
71}
72
73 void BusWatch::toggle()
74{
75 debug_log("watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");
76
77 DefaultWatch::enabled(Watch::enabled());
78}
79
80 BusDispatcher::BusDispatcher() :
81 _running(false)
82{
83 // pipe to create a new fd used to unlock a dispatcher at any
84 // moment (used by leave function)
85 int ret = pipe(_pipe);
86 if (ret == -1) throw Error("PipeError:errno", toString(errno).c_str());
87
88 _fdunlock[0] = _pipe[0];
89 _fdunlock[1] = _pipe[1];
90}
91
92 void BusDispatcher::enter()
93{
94 debug_log("entering dispatcher %p", this);
95
96 _running = true;
97
98 while (_running)
99 {
100 do_iteration();
101
102 for (std::list <Pipe *>::iterator p_it = pipe_list.begin();
103 p_it != pipe_list.end();
104 ++p_it)
105 {
106 Pipe *read_pipe = *p_it;
107 char buffer[1024]; // TODO: should be max pipe size
108 unsigned int nbytes = 0;
109
110 while (read_pipe->read(buffer, nbytes) > 0)
111 {
112 read_pipe->_handler(read_pipe->_data, buffer, nbytes);
113 }
114
115 }
116 }
117
118 debug_log("leaving dispatcher %p", this);
119}
120
121 void BusDispatcher::leave()
122{
123 _running = false;
124
125 int ret = write(_fdunlock[1], "exit", strlen("exit"));
126 if (ret == -1) throw Error("WriteError:errno", toString(errno).c_str());
127
128 close(_fdunlock[1]);
129 close(_fdunlock[0]);
130}
131
132 Pipe *BusDispatcher::add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data)
133{
134 Pipe *new_pipe = new Pipe(handler, data);
135 pipe_list.push_back(new_pipe);
136
137 return new_pipe;
138}
139
140 void BusDispatcher::del_pipe(Pipe *pipe)
141{
142 pipe_list.remove(pipe);
143 delete pipe;
144}
145
146 void BusDispatcher::do_iteration()
147{
148 dispatch_pending();
149 dispatch();
150}
151
152 Timeout *BusDispatcher::add_timeout(Timeout::Internal *ti)
153{
154 BusTimeout *bt = new BusTimeout(ti, this);
155
156 bt->expired = new Callback<BusDispatcher, void, DefaultTimeout &>(this, &BusDispatcher::timeout_expired);
157 bt->data(bt);
158
159 debug_log("added timeout %p (%s) (%d millies)",
160 bt,
161 ((Timeout *)bt)->enabled() ? "on" : "off",
162 ((Timeout *)bt)->interval()
163 );
164
165 return bt;
166}
167
168 void BusDispatcher::rem_timeout(Timeout *t)
169{
170 debug_log("removed timeout %p", t);
171
172 delete t;
173}
174
175 Watch *BusDispatcher::add_watch(Watch::Internal *wi)
176{
177 BusWatch *bw = new BusWatch(wi, this);
178
179 bw->ready = new Callback<BusDispatcher, void, DefaultWatch &>(this, &BusDispatcher::watch_ready);
180 bw->data(bw);
181
182 debug_log("added watch %p (%s) fd=%d flags=%d",
183 bw, ((Watch *)bw)->enabled() ? "on" : "off", ((Watch *)bw)->descriptor(), ((Watch *)bw)->flags());
184
185 return bw;
186}
187
188 void BusDispatcher::rem_watch(Watch *w)
189{
190 debug_log("removed watch %p", w);
191
192 delete w;
193}
194
195 void BusDispatcher::timeout_expired(DefaultTimeout &et)
196{
197 debug_log("timeout %p expired", &et);
198
199 BusTimeout *timeout = reinterpret_cast<BusTimeout *>(et.data());
200
201 timeout->handle();
202}
203
204 void BusDispatcher::watch_ready(DefaultWatch &ew)
205{
206 BusWatch *watch = reinterpret_cast<BusWatch *>(ew.data());
207
208 debug_log("watch %p ready, flags=%d state=%d",
209 watch, ((Watch *)watch)->flags(), watch->state()
210 );
211
212 int flags = 0;
213
214 if (watch->state() & POLLIN)
215 flags |= DBUS_WATCH_READABLE;
216 if (watch->state() & POLLOUT)
217 flags |= DBUS_WATCH_WRITABLE;
218 if (watch->state() & POLLHUP)
219 flags |= DBUS_WATCH_HANGUP;
220 if (watch->state() & POLLERR)
221 flags |= DBUS_WATCH_ERROR;
222
223 watch->handle(flags);
224}
225
DBus::BusDispatcher::pipe_list
std::list< Pipe * > pipe_list
Definition eventloop-integration.h:94
DBus::BusDispatcher::add_pipe
virtual Pipe * add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data)
Definition eventloop-integration.cpp:132
DBus::BusDispatcher::do_iteration
virtual void do_iteration()
Definition eventloop-integration.cpp:146
DBus::BusDispatcher::BusDispatcher
BusDispatcher()
Definition eventloop-integration.cpp:80
DBus::BusDispatcher::_pipe
int _pipe[2]
Definition eventloop-integration.h:93
DBus::BusDispatcher::leave
virtual void leave()
Definition eventloop-integration.cpp:121
DBus::BusDispatcher::del_pipe
virtual void del_pipe(Pipe *pipe)
Definition eventloop-integration.cpp:140
DBus::BusDispatcher::watch_ready
void watch_ready(DefaultWatch &)
Definition eventloop-integration.cpp:204
DBus::BusDispatcher::add_timeout
virtual Timeout * add_timeout(Timeout::Internal *)
Definition eventloop-integration.cpp:152
DBus::BusDispatcher::rem_watch
virtual void rem_watch(Watch *)
Definition eventloop-integration.cpp:188
DBus::BusDispatcher::timeout_expired
void timeout_expired(DefaultTimeout &)
Definition eventloop-integration.cpp:195
DBus::BusDispatcher::enter
virtual void enter()
Definition eventloop-integration.cpp:92
DBus::BusDispatcher::rem_timeout
virtual void rem_timeout(Timeout *)
Definition eventloop-integration.cpp:168
DBus::BusDispatcher::_running
bool _running
Definition eventloop-integration.h:92
DBus::BusDispatcher::add_watch
virtual Watch * add_watch(Watch::Internal *)
Definition eventloop-integration.cpp:175
DBus::BusTimeout
Definition eventloop-integration.h:45
DBus::BusTimeout::BusTimeout
BusTimeout(Timeout::Internal *, BusDispatcher *)
Definition eventloop-integration.cpp:46
DBus::BusTimeout::toggle
void toggle()
Definition eventloop-integration.cpp:52
DBus::BusTimeout::BusDispatcher
friend class BusDispatcher
Definition eventloop-integration.h:50
DBus::BusWatch
Definition eventloop-integration.h:54
DBus::BusWatch::toggle
void toggle()
Definition eventloop-integration.cpp:73
DBus::BusWatch::BusWatch
BusWatch(Watch::Internal *, BusDispatcher *)
Definition eventloop-integration.cpp:59
DBus::BusWatch::BusDispatcher
friend class BusDispatcher
Definition eventloop-integration.h:59
DBus::Callback
Definition util.h:272
DBus::DefaultMainLoop::DefaultWatch
friend class DefaultWatch
Definition eventloop.h:220
DBus::DefaultMainLoop::_fdunlock
int _fdunlock[2]
Definition eventloop.h:210
DBus::DefaultMainLoop::dispatch
virtual void dispatch()
Definition eventloop.cpp:149
DBus::DefaultMainLoop::DefaultTimeout
friend class DefaultTimeout
Definition eventloop.h:219
DBus::DefaultTimeout::DefaultTimeout
DefaultTimeout(int interval, bool repeat, DefaultMainLoop *)
Definition eventloop.cpp:44
DBus::DefaultTimeout::expired
Slot< void, DefaultTimeout & > expired
Definition eventloop.h:90
DBus::DefaultTimeout::enabled
bool enabled()
Definition eventloop.h:54
DBus::DefaultTimeout::data
void * data()
Definition eventloop.h:81
DBus::DefaultWatch::state
int state()
Definition eventloop.h:141
DBus::DefaultWatch::ready
Slot< void, DefaultWatch & > ready
Definition eventloop.h:155
DBus::DefaultWatch::DefaultWatch
DefaultWatch(int fd, int flags, DefaultMainLoop *)
Definition eventloop.cpp:64
DBus::DefaultWatch::data
void * data()
Definition eventloop.h:146
DBus::DefaultWatch::enabled
bool enabled()
Definition eventloop.h:118
DBus::DefaultWatch::flags
int flags()
Definition eventloop.h:132
DBus::Dispatcher::dispatch_pending
void dispatch_pending()
Definition dispatcher.cpp:182
DBus::Error
Definition error.h:40
DBus::Pipe
Definition pipe.h:37
DBus::Pipe::read
ssize_t read(void *buffer, unsigned int &nbytes)
Definition pipe.cpp:73
DBus::Pipe::_handler
void(* _handler)(const void *data, void *buffer, unsigned int nbyte)
Definition pipe.h:56
DBus::Pipe::_data
const void * _data
Definition pipe.h:59
DBus::Timeout
Definition dispatcher.h:36
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::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::descriptor
int descriptor() const
A main loop could poll this descriptor to integrate dbus-c++.
Definition dispatcher.cpp:70
debug.h
eventloop-integration.h
DBus
Definition connection_p.h:42
DBus::toString
std::string toString(const T &thing, int w=0, int p=0)
create std::string from any number
Definition util.h:294
DBus::debug_log
DXXAPI LogFunction debug_log
Definition debug.cpp:55
pipe.h