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 */
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
43using namespace DBus;
44using namespace std;
45
46BusTimeout::BusTimeout(Timeout::Internal *ti, BusDispatcher *bd)
47 : Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd)
48{
50}
51
53{
54 debug_log("timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");
55
57}
58
59BusWatch::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
71}
72
74{
75 debug_log("watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");
76
78}
79
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
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
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
132Pipe *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
141{
142 pipe_list.remove(pipe);
143 delete pipe;
144}
145
147{
149 dispatch();
150}
151
152Timeout *BusDispatcher::add_timeout(Timeout::Internal *ti)
153{
154 BusTimeout *bt = new BusTimeout(ti, this);
155
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
169{
170 debug_log("removed timeout %p", t);
171
172 delete t;
173}
174
175Watch *BusDispatcher::add_watch(Watch::Internal *wi)
176{
177 BusWatch *bw = new BusWatch(wi, this);
178
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
189{
190 debug_log("removed watch %p", w);
191
192 delete w;
193}
194
196{
197 debug_log("timeout %p expired", &et);
198
199 BusTimeout *timeout = reinterpret_cast<BusTimeout *>(et.data());
200
201 timeout->handle();
202}
203
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
std::list< Pipe * > pipe_list
virtual Pipe * add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data)
virtual void del_pipe(Pipe *pipe)
void watch_ready(DefaultWatch &)
virtual Timeout * add_timeout(Timeout::Internal *)
virtual void rem_watch(Watch *)
void timeout_expired(DefaultTimeout &)
virtual void rem_timeout(Timeout *)
virtual Watch * add_watch(Watch::Internal *)
BusWatch(Watch::Internal *, BusDispatcher *)
virtual void dispatch()
Definition: eventloop.cpp:149
Slot< void, DefaultTimeout & > expired
Definition: eventloop.h:90
Slot< void, DefaultWatch & > ready
Definition: eventloop.h:155
ssize_t read(void *buffer, unsigned int &nbytes)
Definition: pipe.cpp:73
void(* _handler)(const void *data, void *buffer, unsigned int nbyte)
Definition: pipe.h:56
const void * _data
Definition: pipe.h:59
bool enabled() const
Definition: dispatcher.cpp:51
bool handle()
Calls the timeout handler for this timeout.
Definition: dispatcher.cpp:56
bool enabled() const
Definition: dispatcher.cpp:91
int flags() const
Gets flags from DBusWatchFlags indicating what conditions should be monitored on the file descriptor.
Definition: dispatcher.cpp:86
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
std::string toString(const T &thing, int w=0, int p=0)
create std::string from any number
Definition: util.h:294
DXXAPI LogFunction debug_log
Definition: debug.cpp:55
void dispatch_pending()
Definition: dispatcher.cpp:182