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 <string.h>
38#include <cassert>
39#include <sys/poll.h>
40#include <fcntl.h>
41#include <unistd.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{
148 _running = true;
149}
150
152{
153 return _running;
154}
155
161
162Timeout *BusDispatcher::add_timeout(Timeout::Internal *ti)
163{
164 BusTimeout *bt = new BusTimeout(ti, this);
165
167 bt->data(bt);
168
169 debug_log("added timeout %p (%s) (%d millies)",
170 bt,
171 ((Timeout *)bt)->enabled() ? "on" : "off",
172 ((Timeout *)bt)->interval()
173 );
174
175 return bt;
176}
177
179{
180 debug_log("removed timeout %p", t);
181
182 delete t;
183}
184
185Watch *BusDispatcher::add_watch(Watch::Internal *wi)
186{
187 BusWatch *bw = new BusWatch(wi, this);
188
190 bw->data(bw);
191
192 debug_log("added watch %p (%s) fd=%d flags=%d",
193 bw, ((Watch *)bw)->enabled() ? "on" : "off", ((Watch *)bw)->descriptor(), ((Watch *)bw)->flags());
194
195 return bw;
196}
197
199{
200 debug_log("removed watch %p", w);
201
202 delete w;
203}
204
206{
207 debug_log("timeout %p expired", &et);
208
209 BusTimeout *timeout = reinterpret_cast<BusTimeout *>(et.data());
210
211 timeout->handle();
212}
213
215{
216 BusWatch *watch = reinterpret_cast<BusWatch *>(ew.data());
217
218 debug_log("watch %p ready, flags=%d state=%d",
219 watch, ((Watch *)watch)->flags(), watch->state()
220 );
221
222 int flags = 0;
223
224 if (watch->state() & POLLIN)
225 flags |= DBUS_WATCH_READABLE;
226 if (watch->state() & POLLOUT)
227 flags |= DBUS_WATCH_WRITABLE;
228 if (watch->state() & POLLHUP)
229 flags |= DBUS_WATCH_HANGUP;
230 if (watch->state() & POLLERR)
231 flags |= DBUS_WATCH_ERROR;
232
233 watch->handle(flags);
234}
235
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 *)
BusTimeout(Timeout::Internal *, BusDispatcher *)
BusWatch(Watch::Internal *, BusDispatcher *)
virtual void dispatch()
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
bool handle()
Calls the timeout handler for this timeout.
bool enabled() const
int flags() const
Gets flags from DBusWatchFlags indicating what conditions should be monitored on the file descriptor.
bool handle(int flags)
Called to notify the D-Bus library when a previously-added watch is ready for reading or writing,...
std::string toString(const T &thing, int w=0, int p=0)
create std::string from any number
Definition util.h:297
DXXAPI LogFunction debug_log
Definition debug.cpp:55