summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Volz <andreas@frodo.mittelerde>2010-12-05 23:09:30 +0100
committerAndreas Volz <andreas@frodo.mittelerde>2010-12-05 23:09:30 +0100
commit2a42e69250ab1d57e159aca0109a6b24c3182da8 (patch)
tree2856238cfc270d994d9e19bd3538677f3815b0c4
parent9f2fdd36d39b00687d86425e522fe68b53713777 (diff)
parent2379d37c3bfb894ea735d0af40368f2aa5afa72a (diff)
downloaddbus-c++-2a42e69250ab1d57e159aca0109a6b24c3182da8.tar.gz
Merge branch 'master' of git@gitorious.org:dbus-cplusplus/mainline
-rw-r--r--.gitignore22
-rw-r--r--Makefile.am2
-rwxr-xr-xbootstrap2
-rw-r--r--configure.ac3
-rw-r--r--examples/Makefile.am2
-rw-r--r--examples/echo/echo-client.cpp79
-rw-r--r--include/dbus-c++/dbus.h1
-rw-r--r--include/dbus-c++/dispatcher.h2
-rw-r--r--include/dbus-c++/ecore-integration.h6
-rw-r--r--include/dbus-c++/eventloop-integration.h27
-rw-r--r--include/dbus-c++/glib-integration.h4
-rw-r--r--include/dbus-c++/pipe.h69
-rw-r--r--include/dbus-c++/property.h2
-rw-r--r--include/dbus-c++/util.h22
-rw-r--r--m4/acx_pthread.m4 (renamed from config/acx_pthread.m4)0
-rw-r--r--src/Makefile.am3
-rw-r--r--src/ecore-integration.cpp6
-rw-r--r--src/eventloop-integration.cpp56
-rw-r--r--src/eventloop.cpp4
-rw-r--r--src/pipe.cpp84
20 files changed, 339 insertions, 57 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3cfba9c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,22 @@
+Makefile.in
+aclocal.m4
+autom4te.cache/
+config.guess
+config.h.in
+config.sub
+configure
+data/Makefile.in
+depcomp
+doc/Makefile.in
+examples/Makefile.in
+examples/echo/Makefile.in
+examples/ecore/Makefile.in
+examples/glib/Makefile.in
+examples/hal/Makefile.in
+examples/properties/Makefile.in
+install-sh
+ltmain.sh
+m4/
+missing
+src/Makefile.in
+tools/Makefile.in
diff --git a/Makefile.am b/Makefile.am
index 5df2cc8..912f64b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,6 +2,8 @@ SUBDIRS = src tools data doc examples
EXTRA_DIST = autogen.sh bootstrap libdbus-c++.spec libdbus-c++.spec.in
+ACLOCAL_AMFLAGS = -I m4
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = dbus-c++-1.pc
diff --git a/bootstrap b/bootstrap
index 292c981..6b2c608 100755
--- a/bootstrap
+++ b/bootstrap
@@ -58,7 +58,7 @@ fi
echo "Running libtoolize..."
libtoolize --force --copy
-aclocalinclude="$ACLOCAL_FLAGS -I config"
+aclocalinclude="$ACLOCAL_FLAGS -I m4"
echo "Running aclocal $aclocalinclude ..."
aclocal $aclocalinclude
diff --git a/configure.ac b/configure.ac
index 42f7199..1cdbb6f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,10 +1,11 @@
# Autojunk script for libdbus-c++
AC_PREREQ(2.59)
-AC_INIT([libdbus-c++], 0.5.0, [shackan@gmail.com])
+AC_INIT([libdbus-c++], 0.6.0-pre1, [andreas.volz@tux-style.com])
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
AM_CONFIG_HEADER([config.h])
+AC_CONFIG_MACRO_DIR([m4])
AC_CANONICAL_HOST
diff --git a/examples/Makefile.am b/examples/Makefile.am
index a940bc8..40fa245 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = properties echo hal glib ecore
+DIST_SUBDIRS = properties echo hal glib ecore
MAINTAINERCLEANFILES = \
Makefile.in
diff --git a/examples/echo/echo-client.cpp b/examples/echo/echo-client.cpp
index 8fe7ad7..f84c093 100644
--- a/examples/echo/echo-client.cpp
+++ b/examples/echo/echo-client.cpp
@@ -7,6 +7,7 @@
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
+#include <cstring>
using namespace std;
@@ -27,32 +28,31 @@ void EchoClient::Echoed(const DBus::Variant &value)
* For some strange reason, libdbus frequently dies with an OOM
*/
-static const int THREADS = 3;
+static const size_t THREADS = 3;
static bool spin = true;
-void *greeter_thread(void *arg)
-{
- DBus::Connection *conn = reinterpret_cast<DBus::Connection *>(arg);
+EchoClient *g_client = NULL;
- EchoClient client(*conn, ECHO_SERVER_PATH, ECHO_SERVER_NAME);
+DBus::Pipe *thread_pipe_list[THREADS];
+DBus::BusDispatcher dispatcher;
+DBus::DefaultTimeout *timeout;
+
+void *greeter_thread(void *arg)
+{
char idstr[16];
+ size_t i = (size_t) arg;
snprintf(idstr, sizeof(idstr), "%lu", pthread_self());
- for (int i = 0; i < 30 && spin; ++i)
- {
- cout << client.Hello(idstr) << endl;
- }
+ thread_pipe_list[i]->write (idstr, strlen (idstr) + 1);
- cout << idstr << " done " << endl;
+ cout << idstr << " done (" << i << ")" << endl;
return NULL;
}
-DBus::BusDispatcher dispatcher;
-
void niam(int sig)
{
spin = false;
@@ -60,32 +60,77 @@ void niam(int sig)
dispatcher.leave();
}
+void handler1 (const void *data, void *buffer, unsigned int nbyte)
+{
+ char *str = (char*) buffer;
+ cout << "buffer1: " << str << ", size: " << nbyte << endl;
+ for (int i = 0; i < 30 && spin; ++i)
+ {
+ cout << "call1: " << g_client->Hello (str) << endl;
+ }
+}
+
+void handler2 (const void *data, void *buffer, unsigned int nbyte)
+{
+ char *str = (char*) buffer;
+ cout << "buffer2: " << str << ", size: " << nbyte <<endl;
+ for (int i = 0; i < 30 && spin; ++i)
+ {
+ cout << "call2: " << g_client->Hello (str) << endl;
+ }
+}
+
+void handler3 (const void *data, void *buffer, unsigned int nbyte)
+{
+ char *str = (char*) buffer;
+ cout << "buffer3: " << str << ", size: " << nbyte <<endl;
+ for (int i = 0; i < 30 && spin; ++i)
+ {
+ cout << "call3: " << g_client->Hello (str) << endl;
+ }
+}
+
int main()
{
+ size_t i;
+
signal(SIGTERM, niam);
signal(SIGINT, niam);
DBus::_init_threading();
- DBus::default_dispatcher = &dispatcher;
+ DBus::default_dispatcher = &dispatcher;
+
+ // increase DBus-C++ frequency
+ new DBus::DefaultTimeout(100, false, &dispatcher);
DBus::Connection conn = DBus::Connection::SessionBus();
+ EchoClient client (conn, ECHO_SERVER_PATH, ECHO_SERVER_NAME);
+ g_client = &client;
+
pthread_t threads[THREADS];
- for (int i = 0; i < THREADS; ++i)
+ thread_pipe_list[0] = dispatcher.add_pipe (handler1, NULL);
+ thread_pipe_list[1] = dispatcher.add_pipe (handler2, NULL);
+ thread_pipe_list[2] = dispatcher.add_pipe (handler3, NULL);
+ for (i = 0; i < THREADS; ++i)
{
- pthread_create(threads+i, NULL, greeter_thread, &conn);
+ pthread_create(threads+i, NULL, greeter_thread, (void*) i);
}
-
+
dispatcher.enter();
cout << "terminating" << endl;
- for (int i = 0; i < THREADS; ++i)
+ for (i = 0; i < THREADS; ++i)
{
pthread_join(threads[i], NULL);
}
+ dispatcher.del_pipe (thread_pipe_list[0]);
+ dispatcher.del_pipe (thread_pipe_list[1]);
+ dispatcher.del_pipe (thread_pipe_list[2]);
+
return 0;
}
diff --git a/include/dbus-c++/dbus.h b/include/dbus-c++/dbus.h
index 7dfc164..80893cb 100644
--- a/include/dbus-c++/dbus.h
+++ b/include/dbus-c++/dbus.h
@@ -41,5 +41,6 @@
#include "eventloop.h"
#include "eventloop-integration.h"
#include "introspection.h"
+#include "pipe.h"
#endif//__DBUSXX_DBUS_H
diff --git a/include/dbus-c++/dispatcher.h b/include/dbus-c++/dispatcher.h
index 10179ff..728f9d8 100644
--- a/include/dbus-c++/dispatcher.h
+++ b/include/dbus-c++/dispatcher.h
@@ -44,7 +44,7 @@ public:
/*!
* \brief Gets the timeout interval.
*
- * The dbus_timeout_handle() should be called each time this interval elapses,
+ * The handle() should be called each time this interval elapses,
* starting after it elapses once.
*
* The interval may change during the life of the timeout; if so, the timeout
diff --git a/include/dbus-c++/ecore-integration.h b/include/dbus-c++/ecore-integration.h
index b475533..2b14b27 100644
--- a/include/dbus-c++/ecore-integration.h
+++ b/include/dbus-c++/ecore-integration.h
@@ -47,7 +47,7 @@ private:
void toggle();
- static int timeout_handler( void* );
+ static Eina_Bool timeout_handler( void* );
void _enable();
@@ -69,9 +69,9 @@ private:
void toggle();
- static int watch_handler_read ( void*, Ecore_Fd_Handler *fdh);
+ static Eina_Bool watch_handler_read ( void*, Ecore_Fd_Handler *fdh);
- static int watch_handler_error ( void*, Ecore_Fd_Handler *fdh);
+ static Eina_Bool watch_handler_error ( void*, Ecore_Fd_Handler *fdh);
void _enable();
diff --git a/include/dbus-c++/eventloop-integration.h b/include/dbus-c++/eventloop-integration.h
index b8e02c7..0459ebf 100644
--- a/include/dbus-c++/eventloop-integration.h
+++ b/include/dbus-c++/eventloop-integration.h
@@ -38,6 +38,7 @@ namespace DBus {
*/
class BusDispatcher;
+class Pipe;
class DXXAPI BusTimeout : public Timeout, public DefaultTimeout
{
@@ -60,27 +61,18 @@ friend class BusDispatcher;
class DXXAPI BusDispatcher : public Dispatcher, public DefaultMainLoop
{
public:
-
- int _pipe[2];
-
- BusDispatcher() : _running(false)
- {
- //pipe to create a new fd used to unlock a dispatcher at any
- // moment (used by leave function)
- int ret = pipe(_pipe);
- if (ret == -1) throw Error("PipeError:errno", toString(errno).c_str());
-
- _fdunlock[0] = _pipe[0];
- _fdunlock[1] = _pipe[1];
- }
-
- ~BusDispatcher()
- {}
+ BusDispatcher();
+
+ ~BusDispatcher() {}
virtual void enter();
virtual void leave();
+ virtual Pipe *add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data);
+
+ virtual void del_pipe (Pipe *pipe);
+
virtual void do_iteration();
virtual Timeout *add_timeout(Timeout::Internal *);
@@ -96,8 +88,9 @@ public:
void timeout_expired(DefaultTimeout &);
private:
-
bool _running;
+ int _pipe[2];
+ std::list <Pipe*> pipe_list;
};
} /* namespace DBus */
diff --git a/include/dbus-c++/glib-integration.h b/include/dbus-c++/glib-integration.h
index 76eae5e..0f68852 100644
--- a/include/dbus-c++/glib-integration.h
+++ b/include/dbus-c++/glib-integration.h
@@ -54,9 +54,9 @@ private:
private:
- GSource *_source;
GMainContext *_ctx;
int _priority;
+ GSource *_source;
friend class BusDispatcher;
};
@@ -79,9 +79,9 @@ private:
private:
- GSource *_source;
GMainContext *_ctx;
int _priority;
+ GSource *_source;
friend class BusDispatcher;
};
diff --git a/include/dbus-c++/pipe.h b/include/dbus-c++/pipe.h
new file mode 100644
index 0000000..752d48d
--- /dev/null
+++ b/include/dbus-c++/pipe.h
@@ -0,0 +1,69 @@
+/*
+ *
+ * D-Bus++ - C++ bindings for D-Bus
+ *
+ * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef DBUSXX_PIPE_H
+#define DBUSXX_PIPE_H
+
+/* Project */
+#include "api.h"
+
+/* STD */
+#include <cstdlib>
+
+namespace DBus {
+
+class DXXAPI Pipe
+{
+public:
+ /*!
+ * Write some data into the communication pipe.
+ *
+ * @param buffer The raw data to write.
+ * @param nbytes The number of bytes to write from the buffer.
+ */
+ void write(const void *buffer, unsigned int nbytes);
+
+ ssize_t read(void *buffer, unsigned int &nbytes);
+
+ /*!
+ * Simply write one single byte into the pipe. This is a shortcut
+ * if there's really no data to transport, but to activate the handler.
+ */
+ void signal();
+
+private:
+ void(*_handler)(const void *data, void *buffer, unsigned int nbyte);
+ int _fd_write;
+ int _fd_read;
+ const void *_data;
+
+ // allow construction only in BusDispatcher
+ Pipe (void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data);
+ ~Pipe () {};
+
+friend class BusDispatcher;
+};
+
+} /* namespace DBus */
+
+#endif // DBUSXX_PIPE_H
diff --git a/include/dbus-c++/property.h b/include/dbus-c++/property.h
index 2e909cb..847ae89 100644
--- a/include/dbus-c++/property.h
+++ b/include/dbus-c++/property.h
@@ -46,7 +46,7 @@ public:
T operator() (void) const
{
- return (T)_data->value;
+ return _data->value.operator T();
}
PropertyAdaptor &operator = (const T &t)
diff --git a/include/dbus-c++/util.h b/include/dbus-c++/util.h
index b46732f..8b3806d 100644
--- a/include/dbus-c++/util.h
+++ b/include/dbus-c++/util.h
@@ -28,6 +28,8 @@
#include <sstream>
#include <iostream>
#include <iomanip>
+#include <cassert>
+
#include "api.h"
#include "debug.h"
@@ -232,15 +234,29 @@ public:
R operator()(P param) const
{
- /*if (_cb.get())*/ return _cb->call(param);
+ if (!empty())
+ {
+ return _cb->call(param);
+ }
+
+ // TODO: think about return type in this case
+ // this assert should help me to find the use case where it's needed...
+ //assert (false);
}
R call(P param) const
{
- /*if (_cb.get())*/ return _cb->call(param);
+ if (!empty())
+ {
+ return _cb->call(param);
+ }
+
+ // TODO: think about return type in this case
+ // this assert should help me to find the use case where it's needed...
+ //assert (false);
}
- bool empty()
+ bool empty() const
{
return _cb.get() == 0;
}
diff --git a/config/acx_pthread.m4 b/m4/acx_pthread.m4
index eb09f5a..eb09f5a 100644
--- a/config/acx_pthread.m4
+++ b/m4/acx_pthread.m4
diff --git a/src/Makefile.am b/src/Makefile.am
index 1220db5..538c031 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,13 +36,14 @@ HEADER_FILES = \
$(HEADER_DIR)/api.h \
$(HEADER_DIR)/eventloop.h \
$(HEADER_DIR)/eventloop-integration.h \
+ $(HEADER_DIR)/pipe.h \
$(GLIB_H) $(ECORE_H)
lib_includedir=$(includedir)/dbus-c++-1/dbus-c++/
lib_include_HEADERS = $(HEADER_FILES)
lib_LTLIBRARIES = libdbus-c++-1.la
-libdbus_c___1_la_SOURCES = $(HEADER_FILES) interface.cpp object.cpp introspection.cpp debug.cpp types.cpp connection.cpp connection_p.h property.cpp dispatcher.cpp dispatcher_p.h pendingcall.cpp pendingcall_p.h error.cpp internalerror.h message.cpp message_p.h server.cpp server_p.h eventloop.cpp eventloop-integration.cpp $(GLIB_CPP) $(ECORE_CPP)
+libdbus_c___1_la_SOURCES = $(HEADER_FILES) interface.cpp object.cpp introspection.cpp debug.cpp types.cpp connection.cpp connection_p.h property.cpp dispatcher.cpp dispatcher_p.h pendingcall.cpp pendingcall_p.h error.cpp internalerror.h message.cpp message_p.h server.cpp server_p.h eventloop.cpp eventloop-integration.cpp pipe.cpp $(GLIB_CPP) $(ECORE_CPP)
libdbus_c___1_la_LIBADD = $(dbus_LIBS) $(glib_LIBS) $(pthread_LIBS) $(ecore_LIBS)
libdbus_c___1_la_LDFLAGS = -no-undefined
diff --git a/src/ecore-integration.cpp b/src/ecore-integration.cpp
index e530e06..f1e24e7 100644
--- a/src/ecore-integration.cpp
+++ b/src/ecore-integration.cpp
@@ -50,7 +50,7 @@ void Ecore::BusTimeout::toggle()
else _disable();
}
-int Ecore::BusTimeout::timeout_handler( void *data )
+Eina_Bool Ecore::BusTimeout::timeout_handler( void *data )
{
Ecore::BusTimeout* t = reinterpret_cast<Ecore::BusTimeout*>(data);
@@ -118,7 +118,7 @@ void Ecore::BusWatch::toggle()
else _disable();
}
-int Ecore::BusWatch::watch_handler_read( void *data, Ecore_Fd_Handler *fdh )
+Eina_Bool Ecore::BusWatch::watch_handler_read( void *data, Ecore_Fd_Handler *fdh )
{
Ecore::BusWatch* w = reinterpret_cast<Ecore::BusWatch*>(data);
@@ -133,7 +133,7 @@ int Ecore::BusWatch::watch_handler_read( void *data, Ecore_Fd_Handler *fdh )
return 1;
}
-int Ecore::BusWatch::watch_handler_error( void *data, Ecore_Fd_Handler *fdh )
+Eina_Bool Ecore::BusWatch::watch_handler_error( void *data, Ecore_Fd_Handler *fdh )
{
//Ecore::BusWatch* w = reinterpret_cast<Ecore::BusWatch*>(data);
diff --git a/src/eventloop-integration.cpp b/src/eventloop-integration.cpp
index 8b9c49b..0c86ffb 100644
--- a/src/eventloop-integration.cpp
+++ b/src/eventloop-integration.cpp
@@ -25,17 +25,22 @@
#include <config.h>
#endif
-#include <string.h>
-
+/* Project */
#include <dbus-c++/eventloop-integration.h>
#include <dbus-c++/debug.h>
+#include <dbus-c++/pipe.h>
-#include <sys/poll.h>
-
+/* DBus */
#include <dbus/dbus.h>
-#include <errno.h>
+
+/* STD */
+#include <string.h>
+#include <cassert>
+#include <sys/poll.h>
+#include <fcntl.h>
using namespace DBus;
+using namespace std;
BusTimeout::BusTimeout(Timeout::Internal *ti, BusDispatcher *bd)
: Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd)
@@ -71,6 +76,18 @@ void BusWatch::toggle()
DefaultWatch::enabled(Watch::enabled());
}
+BusDispatcher::BusDispatcher() :
+ _running(false)
+{
+ // pipe to create a new fd used to unlock a dispatcher at any
+ // moment (used by leave function)
+ int ret = pipe(_pipe);
+ if (ret == -1) throw Error("PipeError:errno", toString(errno).c_str());
+
+ _fdunlock[0] = _pipe[0];
+ _fdunlock[1] = _pipe[1];
+}
+
void BusDispatcher::enter()
{
debug_log("entering dispatcher %p", this);
@@ -80,6 +97,21 @@ void BusDispatcher::enter()
while (_running)
{
do_iteration();
+
+ for (std::list <Pipe*>::iterator p_it = pipe_list.begin ();
+ p_it != pipe_list.end ();
+ ++p_it)
+ {
+ Pipe* read_pipe = *p_it;
+ char buffer[1024]; // TODO: should be max pipe size
+ unsigned int nbytes = 0;
+
+ while (read_pipe->read(buffer, nbytes) > 0)
+ {
+ read_pipe->_handler (read_pipe->_data, buffer, nbytes);
+ }
+
+ }
}
debug_log("leaving dispatcher %p", this);
@@ -96,6 +128,20 @@ void BusDispatcher::leave()
close(_fdunlock[0]);
}
+Pipe *BusDispatcher::add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data)
+{
+ Pipe *new_pipe = new Pipe (handler, data);
+ pipe_list.push_back (new_pipe);
+
+ return new_pipe;
+}
+
+void BusDispatcher::del_pipe (Pipe *pipe)
+{
+ pipe_list.remove (pipe);
+ delete pipe;
+}
+
void BusDispatcher::do_iteration()
{
dispatch_pending();
diff --git a/src/eventloop.cpp b/src/eventloop.cpp
index 76b94f8..eb2ce85 100644
--- a/src/eventloop.cpp
+++ b/src/eventloop.cpp
@@ -34,6 +34,7 @@
#include <dbus/dbus.h>
using namespace DBus;
+using namespace std;
static double millis(timeval tv)
{
@@ -108,7 +109,8 @@ void DefaultMutex::unlock()
pthread_mutex_unlock(&_mutex);
}
-DefaultMainLoop::DefaultMainLoop()
+DefaultMainLoop::DefaultMainLoop() :
+ _mutex_w(true)
{
}
diff --git a/src/pipe.cpp b/src/pipe.cpp
new file mode 100644
index 0000000..96f1b30
--- /dev/null
+++ b/src/pipe.cpp
@@ -0,0 +1,84 @@
+/*
+ *
+ * D-Bus++ - C++ bindings for D-Bus
+ *
+ * Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* Project */
+#include <dbus-c++/pipe.h>
+#include <dbus-c++/util.h>
+#include <dbus-c++/error.h>
+
+/* STD */
+#include <unistd.h>
+#include <sys/poll.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <cassert>
+
+using namespace DBus;
+using namespace std;
+
+Pipe::Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data) :
+ _handler(handler),
+ _fd_write (0),
+ _fd_read (0),
+ _data(data)
+{
+ int fd[2];
+
+ if(pipe(fd) == 0)
+ {
+ _fd_read = fd[0];
+ _fd_write = fd[1];
+ fcntl(_fd_read, F_SETFL, O_NONBLOCK);
+ }
+ else
+ {
+ throw Error("PipeError:errno", toString(errno).c_str());
+ }
+}
+
+void Pipe::write(const void *buffer, unsigned int nbytes)
+{
+ // first write the size into the pipe...
+ ::write(_fd_write, static_cast <const void*> (&nbytes), sizeof(nbytes));
+
+ // ...then write the real data
+ ::write(_fd_write, buffer, nbytes);
+}
+
+ssize_t Pipe::read(void *buffer, unsigned int &nbytes)
+{
+ // first read the size from the pipe...
+ ::read(_fd_read, &nbytes, sizeof (nbytes));
+
+ //ssize_t size = 0;
+ return ::read(_fd_read, buffer, nbytes);
+}
+
+void Pipe::signal()
+{
+ ::write(_fd_write, '\0', 1);
+}