From 9ac4f0252f0784e8594b41e578e6d04f89835d13 Mon Sep 17 00:00:00 2001 From: Andreas Volz Date: Tue, 13 Jul 2010 23:12:50 +0200 Subject: [PATCH 01/11] compile against latest ecore --- include/dbus-c++/ecore-integration.h | 6 +++--- src/ecore-integration.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) 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/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(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(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(data); From 8a3fb381a1b53bef45b997c52a9cf115e9c40515 Mon Sep 17 00:00:00 2001 From: Andreas Volz Date: Sat, 31 Jul 2010 00:20:51 +0200 Subject: [PATCH 02/11] added pipe mechanism for default main loop to synchronize with other threads --- examples/echo/echo-client.cpp | 61 +++++++++++++++---- include/dbus-c++/eventloop-integration.h | 56 ++++++++++++------ src/eventloop-integration.cpp | 74 ++++++++++++++++++++++++ 3 files changed, 163 insertions(+), 28 deletions(-) diff --git a/examples/echo/echo-client.cpp b/examples/echo/echo-client.cpp index 8fe7ad7..f6d59a8 100644 --- a/examples/echo/echo-client.cpp +++ b/examples/echo/echo-client.cpp @@ -7,6 +7,7 @@ #include #include #include +#include using namespace std; @@ -31,22 +32,20 @@ static const int THREADS = 3; static bool spin = true; +EchoClient *g_client = NULL; + +DBus::Pipe *thread_pipe_list[THREADS]; + void *greeter_thread(void *arg) { - DBus::Connection *conn = reinterpret_cast(arg); - - EchoClient client(*conn, ECHO_SERVER_PATH, ECHO_SERVER_NAME); - char idstr[16]; + int i = (int) 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; } @@ -60,6 +59,36 @@ void niam(int sig) dispatcher.leave(); } +void handler1 (const void *data, void *buffer, unsigned int nbyte) +{ + char *str = (char*) buffer; + cout << "buffer1: " << str << endl; + for (int i = 0; i < 30 && spin; ++i) + { + cout << g_client->Hello (str) << endl; + } +} + +void handler2 (const void *data, void *buffer, unsigned int nbyte) +{ + char *str = (char*) buffer; + cout << "buffer2: " << str << endl; + for (int i = 0; i < 30 && spin; ++i) + { + cout << g_client->Hello (str) << endl; + } +} + +void handler3 (const void *data, void *buffer, unsigned int nbyte) +{ + char *str = (char*) buffer; + cout << "buffer3: " << str << endl; + for (int i = 0; i < 30 && spin; ++i) + { + cout << g_client->Hello (str) << endl; + } +} + int main() { signal(SIGTERM, niam); @@ -71,13 +100,19 @@ int main() DBus::Connection conn = DBus::Connection::SessionBus(); + EchoClient client (conn, ECHO_SERVER_PATH, ECHO_SERVER_NAME); + g_client = &client; + pthread_t threads[THREADS]; + 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 (int 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; @@ -87,5 +122,9 @@ int main() 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++/eventloop-integration.h b/include/dbus-c++/eventloop-integration.h index b8e02c7..a061aa8 100644 --- a/include/dbus-c++/eventloop-integration.h +++ b/include/dbus-c++/eventloop-integration.h @@ -57,30 +57,51 @@ class DXXAPI BusWatch : public Watch, public DefaultWatch friend class BusDispatcher; }; +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); + + /*! + * Simply write one single byte into the pipe. This is a shortcut + * if there's really no data to transport, but to actvate 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 BusDipatcher + Pipe () {}; + ~Pipe () {}; + +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 +117,9 @@ public: void timeout_expired(DefaultTimeout &); private: - bool _running; + int _pipe[2]; + std::list pipe_list; }; } /* namespace DBus */ diff --git a/src/eventloop-integration.cpp b/src/eventloop-integration.cpp index 8b9c49b..d20154a 100644 --- a/src/eventloop-integration.cpp +++ b/src/eventloop-integration.cpp @@ -31,11 +31,14 @@ #include #include +#include #include #include +#include using namespace DBus; +using namespace std; BusTimeout::BusTimeout(Timeout::Internal *ti, BusDispatcher *bd) : Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd) @@ -71,6 +74,28 @@ void BusWatch::toggle() DefaultWatch::enabled(Watch::enabled()); } +void Pipe::write(const void *buffer, unsigned int nbytes) +{ + ::write(fd_write, buffer, nbytes); +} + +void Pipe::signal() +{ + ::write(fd_write, '\0', 1); +} + +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 +105,27 @@ void BusDispatcher::enter() while (_running) { do_iteration(); + + for (std::list ::const_iterator p_it = pipe_list.begin (); + p_it != pipe_list.end (); + ++p_it) + { + const Pipe* read_pipe = *p_it; + char buf; + char buf_str[1024]; + int i = 0; + + while (read(read_pipe->fd_read, &buf, 1) > 0) + { + buf_str[i] = buf; + ++i; + } + + if (i > 0) + { + read_pipe->_handler (read_pipe->data, buf_str, i); + } + } } debug_log("leaving dispatcher %p", this); @@ -96,6 +142,34 @@ void BusDispatcher::leave() close(_fdunlock[0]); } +Pipe *BusDispatcher::add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data) +{ + int fd[2]; + Pipe *new_pipe = new Pipe (); + new_pipe->_handler = handler; + new_pipe->data = data; + pipe_list.push_back (new_pipe); + + if (pipe(fd) == 0) + { + new_pipe->fd_read = fd[0]; + new_pipe->fd_write = fd[1]; + fcntl(new_pipe->fd_read, F_SETFL, O_NONBLOCK); + } + else + { + throw Error("PipeError:errno", toString(errno).c_str()); + } + + return new_pipe; +} + +void BusDispatcher::del_pipe (Pipe *pipe) +{ + pipe_list.remove (pipe); + delete pipe; +} + void BusDispatcher::do_iteration() { dispatch_pending(); From 4e6b136fe07ec539c439416ab58375e1a3edb195 Mon Sep 17 00:00:00 2001 From: Andreas Volz Date: Wed, 4 Aug 2010 00:01:23 +0200 Subject: [PATCH 03/11] Commit 1979ced0e0741caae3299c7f94733ba4d62a1e65 from Hubert Figuiere --- examples/Makefile.am | 2 +- include/dbus-c++/property.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/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) From 398da16b4757576f5409e1baaf1be4fe3a4bfc1f Mon Sep 17 00:00:00 2001 From: Andreas Volz Date: Wed, 4 Aug 2010 00:05:55 +0200 Subject: [PATCH 04/11] preserve m4 warning --- Makefile.am | 2 ++ bootstrap | 2 +- configure.ac | 1 + {config => m4}/acx_pthread.m4 | 0 4 files changed, 4 insertions(+), 1 deletion(-) rename {config => m4}/acx_pthread.m4 (100%) 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 2054a07..16042db 100644 --- a/configure.ac +++ b/configure.ac @@ -5,6 +5,7 @@ AC_INIT([libdbus-c++], 0.5.0, [shackan@gmail.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/config/acx_pthread.m4 b/m4/acx_pthread.m4 similarity index 100% rename from config/acx_pthread.m4 rename to m4/acx_pthread.m4 From 1dcda93a6db7b8f430898e4b4f44f6006ed1d5f5 Mon Sep 17 00:00:00 2001 From: Andreas Volz Date: Wed, 4 Aug 2010 00:10:37 +0200 Subject: [PATCH 05/11] autor changed in configure.ac --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 16042db..bb5fc01 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # Autojunk script for libdbus-c++ AC_PREREQ(2.59) -AC_INIT([libdbus-c++], 0.5.0, [shackan@gmail.com]) +AC_INIT([libdbus-c++], 0.5.0, [andreas.volz@tux-style.com]) AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) AM_CONFIG_HEADER([config.h]) From a416700e448b336a3443547db67f5c62178210f3 Mon Sep 17 00:00:00 2001 From: Andreas Volz Date: Wed, 11 Aug 2010 22:31:37 +0200 Subject: [PATCH 06/11] minor --- include/dbus-c++/eventloop-integration.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dbus-c++/eventloop-integration.h b/include/dbus-c++/eventloop-integration.h index a061aa8..213695d 100644 --- a/include/dbus-c++/eventloop-integration.h +++ b/include/dbus-c++/eventloop-integration.h @@ -70,7 +70,7 @@ public: /*! * Simply write one single byte into the pipe. This is a shortcut - * if there's really no data to transport, but to actvate the handler. + * if there's really no data to transport, but to activate the handler. */ void signal(); @@ -80,7 +80,7 @@ private: int fd_read; const void *data; - // allow construction only in BusDipatcher + // allow construction only in BusDispatcher Pipe () {}; ~Pipe () {}; From f0dcaa239f589106328fe325d498bbc810b2805a Mon Sep 17 00:00:00 2001 From: Andreas Volz Date: Thu, 12 Aug 2010 22:48:05 +0200 Subject: [PATCH 07/11] moved pipe to extra files --- include/dbus-c++/dbus.h | 1 + include/dbus-c++/eventloop-integration.h | 31 +---------- include/dbus-c++/pipe.h | 67 ++++++++++++++++++++++++ src/Makefile.am | 3 +- src/eventloop-integration.cpp | 12 +---- src/pipe.cpp | 51 ++++++++++++++++++ 6 files changed, 124 insertions(+), 41 deletions(-) create mode 100644 include/dbus-c++/pipe.h create mode 100644 src/pipe.cpp 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++/eventloop-integration.h b/include/dbus-c++/eventloop-integration.h index 213695d..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 { @@ -57,36 +58,6 @@ class DXXAPI BusWatch : public Watch, public DefaultWatch friend class BusDispatcher; }; -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); - - /*! - * 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 () {}; - ~Pipe () {}; - -friend class BusDispatcher; -}; - class DXXAPI BusDispatcher : public Dispatcher, public DefaultMainLoop { public: diff --git a/include/dbus-c++/pipe.h b/include/dbus-c++/pipe.h new file mode 100644 index 0000000..c994b6e --- /dev/null +++ b/include/dbus-c++/pipe.h @@ -0,0 +1,67 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante + * + * + * 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 + +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); + + /*! + * 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 (); + ~Pipe () {}; + +friend class BusDispatcher; +}; + +} /* namespace DBus */ + +#endif // DBUSXX_PIPE_H diff --git a/src/Makefile.am b/src/Makefile.am index 1220db5..6c7eec4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,7 +42,8 @@ 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 $(GLIB_CPP) $(ECORE_CPP) \ + pipe.cpp pipe.h libdbus_c___1_la_LIBADD = $(dbus_LIBS) $(glib_LIBS) $(pthread_LIBS) $(ecore_LIBS) libdbus_c___1_la_LDFLAGS = -no-undefined diff --git a/src/eventloop-integration.cpp b/src/eventloop-integration.cpp index d20154a..e4a9ad3 100644 --- a/src/eventloop-integration.cpp +++ b/src/eventloop-integration.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -74,16 +75,6 @@ void BusWatch::toggle() DefaultWatch::enabled(Watch::enabled()); } -void Pipe::write(const void *buffer, unsigned int nbytes) -{ - ::write(fd_write, buffer, nbytes); -} - -void Pipe::signal() -{ - ::write(fd_write, '\0', 1); -} - BusDispatcher::BusDispatcher() : _running(false) { @@ -155,6 +146,7 @@ Pipe *BusDispatcher::add_pipe(void(*handler)(const void *data, void *buffer, uns new_pipe->fd_read = fd[0]; new_pipe->fd_write = fd[1]; fcntl(new_pipe->fd_read, F_SETFL, O_NONBLOCK); + fcntl(new_pipe->fd_write, F_SETFL, O_NONBLOCK); } else { diff --git a/src/pipe.cpp b/src/pipe.cpp new file mode 100644 index 0000000..6045e0b --- /dev/null +++ b/src/pipe.cpp @@ -0,0 +1,51 @@ +/* + * + * D-Bus++ - C++ bindings for D-Bus + * + * Copyright (C) 2005-2007 Paolo Durante + * + * + * 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 +#endif + +#include + +#include + +using namespace DBus; +using namespace std; + +Pipe::Pipe () : + _handler (NULL), + fd_write (0), + fd_read (0), + data (NULL) +{ +} + +void Pipe::write(const void *buffer, unsigned int nbytes) +{ + ::write(fd_write, buffer, nbytes); +} + +void Pipe::signal() +{ + ::write(fd_write, '\0', 1); +} From 9af6f707eb62fa02d9ef473ab4cc87ebfdc1c37b Mon Sep 17 00:00:00 2001 From: Andreas Volz Date: Thu, 12 Aug 2010 23:14:45 +0200 Subject: [PATCH 08/11] ok, now at least the structure is better but there's still a problem with the new mechanism as the size of the data isn't put into the pipe. I need to fix tis before someone could really use it... --- include/dbus-c++/pipe.h | 10 +++++---- src/Makefile.am | 4 ++-- src/eventloop-integration.cpp | 38 +++++++++++----------------------- src/pipe.cpp | 39 ++++++++++++++++++++++++++++------- 4 files changed, 52 insertions(+), 39 deletions(-) diff --git a/include/dbus-c++/pipe.h b/include/dbus-c++/pipe.h index c994b6e..393f39d 100644 --- a/include/dbus-c++/pipe.h +++ b/include/dbus-c++/pipe.h @@ -43,6 +43,8 @@ public: */ 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. @@ -51,12 +53,12 @@ public: private: void(*_handler)(const void *data, void *buffer, unsigned int nbyte); - int fd_write; - int fd_read; - const void *data; + int _fd_write; + int _fd_read; + const void *_data; // allow construction only in BusDispatcher - Pipe (); + Pipe (void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data); ~Pipe () {}; friend class BusDispatcher; diff --git a/src/Makefile.am b/src/Makefile.am index 6c7eec4..538c031 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,14 +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) \ - pipe.cpp pipe.h +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/eventloop-integration.cpp b/src/eventloop-integration.cpp index e4a9ad3..689f2da 100644 --- a/src/eventloop-integration.cpp +++ b/src/eventloop-integration.cpp @@ -25,19 +25,20 @@ #include #endif -#include - +/* Project */ #include #include #include +/* DBus */ +#include + +/* STD */ +#include +#include #include #include -#include -#include -#include - using namespace DBus; using namespace std; @@ -97,16 +98,16 @@ void BusDispatcher::enter() { do_iteration(); - for (std::list ::const_iterator p_it = pipe_list.begin (); + for (std::list ::iterator p_it = pipe_list.begin (); p_it != pipe_list.end (); ++p_it) { - const Pipe* read_pipe = *p_it; + Pipe* read_pipe = *p_it; char buf; char buf_str[1024]; int i = 0; - while (read(read_pipe->fd_read, &buf, 1) > 0) + while (read_pipe->read((void*) &buf, 1) > 0) { buf_str[i] = buf; ++i; @@ -114,7 +115,7 @@ void BusDispatcher::enter() if (i > 0) { - read_pipe->_handler (read_pipe->data, buf_str, i); + read_pipe->_handler (read_pipe->_data, buf_str, i); } } } @@ -135,24 +136,9 @@ void BusDispatcher::leave() Pipe *BusDispatcher::add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data) { - int fd[2]; - Pipe *new_pipe = new Pipe (); - new_pipe->_handler = handler; - new_pipe->data = data; + Pipe *new_pipe = new Pipe (handler, data); pipe_list.push_back (new_pipe); - if (pipe(fd) == 0) - { - new_pipe->fd_read = fd[0]; - new_pipe->fd_write = fd[1]; - fcntl(new_pipe->fd_read, F_SETFL, O_NONBLOCK); - fcntl(new_pipe->fd_write, F_SETFL, O_NONBLOCK); - } - else - { - throw Error("PipeError:errno", toString(errno).c_str()); - } - return new_pipe; } diff --git a/src/pipe.cpp b/src/pipe.cpp index 6045e0b..328670a 100644 --- a/src/pipe.cpp +++ b/src/pipe.cpp @@ -25,27 +25,52 @@ #include #endif +/* Project */ #include +#include +#include +/* STD */ #include +#include +#include +#include using namespace DBus; using namespace std; -Pipe::Pipe () : - _handler (NULL), - fd_write (0), - fd_read (0), - data (NULL) +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); + fcntl(_fd_write, F_SETFL, O_NONBLOCK); + } + else + { + throw Error("PipeError:errno", toString(errno).c_str()); + } } void Pipe::write(const void *buffer, unsigned int nbytes) { - ::write(fd_write, buffer, nbytes); + ::write(_fd_write, buffer, nbytes); +} + +ssize_t Pipe::read(void *buffer, unsigned int nbytes) +{ + return ::read(_fd_read, buffer, nbytes); } void Pipe::signal() { - ::write(fd_write, '\0', 1); + ::write(_fd_write, '\0', 1); } From dc833f4a89bcb661274e453a5bb92a2d7655faba Mon Sep 17 00:00:00 2001 From: Andreas Volz Date: Tue, 17 Aug 2010 22:43:24 +0200 Subject: [PATCH 09/11] this fixed the correct handling of the default main loop but setting another DefaultTimeout isn't nice. I've to look later again into the problem. Maybe I did it wrong. Currently there's a compiler warning that could be ignores as long as Slot is created with void parameter, but I consider this as bug in the long time and I've to fix it!! --- examples/echo/echo-client.cpp | 22 +++++++++++++--------- include/dbus-c++/dispatcher.h | 2 +- include/dbus-c++/glib-integration.h | 4 ++-- include/dbus-c++/pipe.h | 2 +- include/dbus-c++/util.h | 22 +++++++++++++++++++--- src/eventloop-integration.cpp | 18 ++++++------------ src/eventloop.cpp | 1 + src/pipe.cpp | 14 +++++++++++--- 8 files changed, 54 insertions(+), 31 deletions(-) diff --git a/examples/echo/echo-client.cpp b/examples/echo/echo-client.cpp index f6d59a8..f01f23a 100644 --- a/examples/echo/echo-client.cpp +++ b/examples/echo/echo-client.cpp @@ -36,6 +36,9 @@ EchoClient *g_client = NULL; DBus::Pipe *thread_pipe_list[THREADS]; +DBus::BusDispatcher dispatcher; +DBus::DefaultTimeout *timeout; + void *greeter_thread(void *arg) { char idstr[16]; @@ -50,8 +53,6 @@ void *greeter_thread(void *arg) return NULL; } -DBus::BusDispatcher dispatcher; - void niam(int sig) { spin = false; @@ -62,30 +63,30 @@ void niam(int sig) void handler1 (const void *data, void *buffer, unsigned int nbyte) { char *str = (char*) buffer; - cout << "buffer1: " << str << endl; + cout << "buffer1: " << str << ", size: " << nbyte << endl; for (int i = 0; i < 30 && spin; ++i) { - cout << g_client->Hello (str) << endl; + cout << "call1: " << g_client->Hello (str) << endl; } } void handler2 (const void *data, void *buffer, unsigned int nbyte) { char *str = (char*) buffer; - cout << "buffer2: " << str << endl; + cout << "buffer2: " << str << ", size: " << nbyte <Hello (str) << endl; + cout << "call2: " << g_client->Hello (str) << endl; } } void handler3 (const void *data, void *buffer, unsigned int nbyte) { char *str = (char*) buffer; - cout << "buffer3: " << str << endl; + cout << "buffer3: " << str << ", size: " << nbyte <Hello (str) << endl; + cout << "call3: " << g_client->Hello (str) << endl; } } @@ -96,7 +97,10 @@ int main() 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(); 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++/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 index 393f39d..752d48d 100644 --- a/include/dbus-c++/pipe.h +++ b/include/dbus-c++/pipe.h @@ -43,7 +43,7 @@ public: */ void write(const void *buffer, unsigned int nbytes); - ssize_t read(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 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 #include #include +#include + #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/src/eventloop-integration.cpp b/src/eventloop-integration.cpp index 689f2da..0c86ffb 100644 --- a/src/eventloop-integration.cpp +++ b/src/eventloop-integration.cpp @@ -103,20 +103,14 @@ void BusDispatcher::enter() ++p_it) { Pipe* read_pipe = *p_it; - char buf; - char buf_str[1024]; - int i = 0; + char buffer[1024]; // TODO: should be max pipe size + unsigned int nbytes = 0; - while (read_pipe->read((void*) &buf, 1) > 0) - { - buf_str[i] = buf; - ++i; - } + while (read_pipe->read(buffer, nbytes) > 0) + { + read_pipe->_handler (read_pipe->_data, buffer, nbytes); + } - if (i > 0) - { - read_pipe->_handler (read_pipe->_data, buf_str, i); - } } } diff --git a/src/eventloop.cpp b/src/eventloop.cpp index 76b94f8..0268162 100644 --- a/src/eventloop.cpp +++ b/src/eventloop.cpp @@ -34,6 +34,7 @@ #include using namespace DBus; +using namespace std; static double millis(timeval tv) { diff --git a/src/pipe.cpp b/src/pipe.cpp index 328670a..96f1b30 100644 --- a/src/pipe.cpp +++ b/src/pipe.cpp @@ -35,6 +35,7 @@ #include #include #include +#include using namespace DBus; using namespace std; @@ -52,7 +53,6 @@ Pipe::Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), c _fd_read = fd[0]; _fd_write = fd[1]; fcntl(_fd_read, F_SETFL, O_NONBLOCK); - fcntl(_fd_write, F_SETFL, O_NONBLOCK); } else { @@ -62,11 +62,19 @@ Pipe::Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), c void Pipe::write(const void *buffer, unsigned int nbytes) { + // first write the size into the pipe... + ::write(_fd_write, static_cast (&nbytes), sizeof(nbytes)); + + // ...then write the real data ::write(_fd_write, buffer, nbytes); } -ssize_t Pipe::read(void *buffer, unsigned int 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); } From 8f064c4b084312424408aab3367240324ca2d456 Mon Sep 17 00:00:00 2001 From: Andreas Volz Date: Fri, 8 Oct 2010 00:22:58 +0200 Subject: [PATCH 10/11] added patches from: Roman Fietze --- .gitignore | 22 ++++++++++++++++++++++ configure.ac | 2 +- examples/echo/echo-client.cpp | 10 ++++++---- 3 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 .gitignore 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/configure.ac b/configure.ac index bb5fc01..a570fd4 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # Autojunk script for libdbus-c++ AC_PREREQ(2.59) -AC_INIT([libdbus-c++], 0.5.0, [andreas.volz@tux-style.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]) diff --git a/examples/echo/echo-client.cpp b/examples/echo/echo-client.cpp index f01f23a..f84c093 100644 --- a/examples/echo/echo-client.cpp +++ b/examples/echo/echo-client.cpp @@ -28,7 +28,7 @@ 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; @@ -42,7 +42,7 @@ DBus::DefaultTimeout *timeout; void *greeter_thread(void *arg) { char idstr[16]; - int i = (int) arg; + size_t i = (size_t) arg; snprintf(idstr, sizeof(idstr), "%lu", pthread_self()); @@ -92,6 +92,8 @@ void handler3 (const void *data, void *buffer, unsigned int nbyte) int main() { + size_t i; + signal(SIGTERM, niam); signal(SIGINT, niam); @@ -112,7 +114,7 @@ int main() 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 (int i = 0; i < THREADS; ++i) + for (i = 0; i < THREADS; ++i) { pthread_create(threads+i, NULL, greeter_thread, (void*) i); } @@ -121,7 +123,7 @@ int main() cout << "terminating" << endl; - for (int i = 0; i < THREADS; ++i) + for (i = 0; i < THREADS; ++i) { pthread_join(threads[i], NULL); } From 2379d37c3bfb894ea735d0af40368f2aa5afa72a Mon Sep 17 00:00:00 2001 From: Andreas Volz Date: Fri, 8 Oct 2010 00:35:45 +0200 Subject: [PATCH 11/11] patch from: Von: Mat An: dbus-cplusplus-devel@lists.sourceforge.net Betreff: [dbus-cplusplus-devel] A patch for deadlock, for dbus io error exception in the mainloop critical section. Datum: Mon, 6 Sep 2010 12:24:03 +0800 --- src/eventloop.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/eventloop.cpp b/src/eventloop.cpp index 0268162..eb2ce85 100644 --- a/src/eventloop.cpp +++ b/src/eventloop.cpp @@ -109,7 +109,8 @@ void DefaultMutex::unlock() pthread_mutex_unlock(&_mutex); } -DefaultMainLoop::DefaultMainLoop() +DefaultMainLoop::DefaultMainLoop() : + _mutex_w(true) { }