From 68a722e6d1ab02fea35d691a7340488322b8895d Mon Sep 17 00:00:00 2001 From: admin Date: Sun, 6 Jan 2008 01:58:28 +0100 Subject: [PATCH] * Nested objects introspection patch (David Belser) * More indentation in generated code (David Belser) * Avoid redundant calls to dbus_bus_add_match (David Belser) * Typo in HAVE_PTHREAD_H macro (Olivier Hochreutiner) * Allow other listeners to receive the same signal, if any (Olivier Hochreutiner) --- INSTALL | 50 ++++++++++++++--------------- examples/echo/Makefile.am | 2 +- include/dbus-c++/eventloop.h | 6 ++-- include/dbus-c++/glib-integration.h | 2 +- include/dbus-c++/object.h | 3 ++ src/Makefile.am | 4 ++- src/eventloop.cpp | 8 ++--- src/interface.cpp | 6 +++- src/introspection.cpp | 29 +++++++++++------ src/object.cpp | 43 ++++++++++++++----------- 10 files changed, 89 insertions(+), 64 deletions(-) diff --git a/INSTALL b/INSTALL index 23e5f25..5458714 100644 --- a/INSTALL +++ b/INSTALL @@ -1,8 +1,8 @@ Installation Instructions ************************* -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free -Software Foundation, Inc. +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. @@ -10,7 +10,10 @@ unlimited permission to copy, distribute and modify it. Basic Installation ================== -These are generic installation instructions. +Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -23,9 +26,9 @@ debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is +the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale -cache files.) +cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail @@ -35,20 +38,17 @@ some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. + `./configure' to configure the package for your system. - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. 2. Type `make' to compile the package. @@ -78,7 +78,7 @@ details on some of the pertinent environment variables. by setting variables in the command line or in the environment. Here is an example: - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. @@ -87,17 +87,15 @@ Compiling For Multiple Architectures You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the +own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. Installation Names ================== @@ -190,12 +188,12 @@ them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). Here is a another example: +overridden in the site shell script). - /bin/bash ./configure CONFIG_SHELL=/bin/bash +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: -Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent -configuration-related scripts to be executed by `/bin/bash'. + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== diff --git a/examples/echo/Makefile.am b/examples/echo/Makefile.am index d3d8e56..1ba7065 100644 --- a/examples/echo/Makefile.am +++ b/examples/echo/Makefile.am @@ -1,6 +1,6 @@ EXTRA_DIST = README echo-introspect.xml -AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include noinst_PROGRAMS = echo-server diff --git a/include/dbus-c++/eventloop.h b/include/dbus-c++/eventloop.h index fcf1164..592e46a 100644 --- a/include/dbus-c++/eventloop.h +++ b/include/dbus-c++/eventloop.h @@ -29,7 +29,7 @@ #include "config.h" #endif -#ifdef HAVE_PTHREAD +#ifdef HAVE_PTHREAD_H #include #endif @@ -143,9 +143,9 @@ public: private: -#if defined HAVE_PTHREAD +#if defined HAVE_PTHREAD_H - pthread_mutex _mutex; + pthread_mutex_t _mutex; #elif defined HAVE_WIN32 diff --git a/include/dbus-c++/glib-integration.h b/include/dbus-c++/glib-integration.h index 723c7d8..a60e3f8 100644 --- a/include/dbus-c++/glib-integration.h +++ b/include/dbus-c++/glib-integration.h @@ -32,7 +32,7 @@ #include #include "api.h" -#include "eventloop.h" +#include "dispatcher.h" namespace DBus { diff --git a/include/dbus-c++/object.h b/include/dbus-c++/object.h index 7c3240b..43ad7cc 100644 --- a/include/dbus-c++/object.h +++ b/include/dbus-c++/object.h @@ -104,6 +104,7 @@ public: class ObjectAdaptor; typedef std::list ObjectAdaptorPList; +typedef std::list ObjectPathList; class DXXAPI ObjectAdaptor : public Object, public virtual AdaptorBase { @@ -113,6 +114,8 @@ public: static ObjectAdaptorPList from_path_prefix( const std::string& prefix ); + static ObjectPathList child_nodes_from_prefix( const std::string& prefix ); + struct Private; ObjectAdaptor( Connection& conn, const Path& path ); diff --git a/src/Makefile.am b/src/Makefile.am index b74bb66..64bb40f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,9 +8,11 @@ GLIB_H = $(HEADER_DIR)/glib-integration.h GLIB_CPP = glib-integration.cpp endif +CONFIG_H = $(top_builddir)/include/dbus-c++/config.h + HEADER_DIR = $(top_srcdir)/include/dbus-c++ HEADER_FILES = \ - $(HEADER_DIR)/config.h \ + $(CONFIG_H) \ $(HEADER_DIR)/dbus.h \ $(HEADER_DIR)/types.h \ $(HEADER_DIR)/connection.h \ diff --git a/src/eventloop.cpp b/src/eventloop.cpp index 32a1044..9e6b25b 100644 --- a/src/eventloop.cpp +++ b/src/eventloop.cpp @@ -74,7 +74,7 @@ DefaultWatch::~DefaultWatch() DefaultMutex::DefaultMutex() { -#if defined HAVE_PTHREAD +#if defined HAVE_PTHREAD_H pthread_mutex_init(&_mutex, NULL); @@ -84,7 +84,7 @@ DefaultMutex::DefaultMutex() DefaultMutex::~DefaultMutex() { -#if defined HAVE_PTHREAD +#if defined HAVE_PTHREAD_H pthread_mutex_destroy(&_mutex); @@ -94,7 +94,7 @@ DefaultMutex::~DefaultMutex() void DefaultMutex::lock() { -#if defined HAVE_PTHREAD +#if defined HAVE_PTHREAD_H pthread_mutex_lock(&_mutex); @@ -104,7 +104,7 @@ void DefaultMutex::lock() void DefaultMutex::unlock() { -#if defined HAVE_PTHREAD +#if defined HAVE_PTHREAD_H pthread_mutex_unlock(&_mutex); diff --git a/src/interface.cpp b/src/interface.cpp index 9615973..57a24fa 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -131,7 +131,11 @@ bool InterfaceProxy::dispatch_signal( const SignalMessage& msg ) if( si != _signals.end() ) { si->second.call( msg ); - return true; + // Here we always return false because there might be + // another InterfaceProxy listening for the same signal. + // This way we instruct libdbus-1 to go on dispatching + // the signal. + return false; } else { diff --git a/src/introspection.cpp b/src/introspection.cpp index 7fc7b38..f9da790 100644 --- a/src/introspection.cpp +++ b/src/introspection.cpp @@ -61,7 +61,7 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call ) IntrospectedInterface* const intro = iti->second->introspect(); if(intro) { - xml << "name << "\">"; + xml << "\n\tname << "\">"; for(const IntrospectedProperty* p = intro->properties; p->name; ++p) { @@ -70,18 +70,18 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call ) if(p->read) access += "read"; if(p->write) access += "write"; - xml << "name << "\"" + xml << "\n\t\tname << "\"" << " type=\"" << p->type << "\"" << " access=\"" << access << "\"/>"; } for(const IntrospectedMethod* m = intro->methods; m->args; ++m) { - xml << "name << "\">"; + xml << "\n\t\tname << "\">"; for(const IntrospectedArgument* a = m->args; a->type; ++a) { - xml << "in ? "in" : "out") << "\"" + xml << "\n\t\t\tin ? "in" : "out") << "\"" << " type=\"" << a->type << "\""; if(a->name) xml << " name=\"" << a->name << "\""; @@ -89,12 +89,12 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call ) xml << "/>"; } - xml << ""; + xml << "\n\t\t"; } for(const IntrospectedMethod* m = intro->signals; m->args; ++m) { - xml << "name << "\">"; + xml << "\n\t\tname << "\">"; for(const IntrospectedArgument* a = m->args; a->type; ++a) { @@ -104,12 +104,22 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call ) xml << "/>"; } - xml << ""; + xml << "\n\t\t"; } - xml << ""; + xml << "\n\t"; } } + + const ObjectPathList nodes = ObjectAdaptor::child_nodes_from_prefix(path + '/'); + ObjectPathList::const_iterator oni; + + for(oni = nodes.begin(); oni != nodes.end(); ++oni) + { + xml << "\n\t"; + } + + /* broken const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/'); ObjectAdaptorPList::const_iterator oci; @@ -121,8 +131,9 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call ) xml << ""; } + */ - xml << ""; + xml << "\n"; ReturnMessage reply(call); MessageIter wi = reply.writer(); diff --git a/src/object.cpp b/src/object.cpp index 8f9b8df..1b79a89 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -119,6 +119,31 @@ ObjectAdaptorPList ObjectAdaptor::from_path_prefix( const std::string& prefix ) return ali; } +ObjectPathList ObjectAdaptor::child_nodes_from_prefix( const std::string& prefix ) +{ + ObjectPathList ali; + + ObjectAdaptorTable::iterator ati = _adaptor_table.begin(); + + size_t plen = prefix.length(); + + while(ati != _adaptor_table.end()) + { + if(!strncmp(ati->second->path().c_str(), prefix.c_str(), plen)) + { + std::string p = ati->second->path().substr(plen); + p = p.substr(0,p.find('/')); + ali.push_back(p); + } + ++ati; + } + + ali.sort(); + ali.unique(); + + return ali; +} + ObjectAdaptor::ObjectAdaptor( Connection& conn, const Path& path ) : Object(conn, path, conn.unique_name()) { @@ -138,16 +163,6 @@ void ObjectAdaptor::register_obj() { throw ErrorNoMemory("unable to register object path"); } - else - { - InterfaceAdaptorTable::const_iterator ii = _interfaces.begin(); - while( ii != _interfaces.end() ) - { - std::string im = "type='method_call',interface='"+ii->first+"',path='"+path()+"'"; - conn().add_match(im.c_str()); - ++ii; - } - } _adaptor_table[path()] = this; } @@ -159,14 +174,6 @@ void ObjectAdaptor::unregister_obj() debug_log("unregistering local object %s", path().c_str()); dbus_connection_unregister_object_path(conn()._pvt->conn, path().c_str()); - - InterfaceAdaptorTable::const_iterator ii = _interfaces.begin(); - while( ii != _interfaces.end() ) - { - std::string im = "type='method_call',interface='"+ii->first+"',path='"+path()+"'"; - conn().remove_match(im.c_str()); - ++ii; - } } void ObjectAdaptor::_emit_signal( SignalMessage& sig )