* 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)
This commit is contained in:
admin 2008-01-06 01:58:28 +01:00
parent ecd2428049
commit 68a722e6d1
10 changed files with 89 additions and 64 deletions

50
INSTALL
View file

@ -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
======================

View file

@ -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

View file

@ -29,7 +29,7 @@
#include "config.h"
#endif
#ifdef HAVE_PTHREAD
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#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

View file

@ -32,7 +32,7 @@
#include <glib.h>
#include "api.h"
#include "eventloop.h"
#include "dispatcher.h"
namespace DBus {

View file

@ -104,6 +104,7 @@ public:
class ObjectAdaptor;
typedef std::list<ObjectAdaptor*> ObjectAdaptorPList;
typedef std::list<std::string> 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 );

View file

@ -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 \

View file

@ -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);

View file

@ -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
{

View file

@ -61,7 +61,7 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
IntrospectedInterface* const intro = iti->second->introspect();
if(intro)
{
xml << "<interface name=\"" << intro->name << "\">";
xml << "\n\t<interface name=\"" << intro->name << "\">";
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 << "<property name=\"" << p->name << "\""
xml << "\n\t\t<property name=\"" << p->name << "\""
<< " type=\"" << p->type << "\""
<< " access=\"" << access << "\"/>";
}
for(const IntrospectedMethod* m = intro->methods; m->args; ++m)
{
xml << "<method name=\"" << m->name << "\">";
xml << "\n\t\t<method name=\"" << m->name << "\">";
for(const IntrospectedArgument* a = m->args; a->type; ++a)
{
xml << "<arg direction=\"" << (a->in ? "in" : "out") << "\""
xml << "\n\t\t\t<arg direction=\"" << (a->in ? "in" : "out") << "\""
<< " type=\"" << a->type << "\"";
if(a->name) xml << " name=\"" << a->name << "\"";
@ -89,12 +89,12 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
xml << "/>";
}
xml << "</method>";
xml << "\n\t\t</method>";
}
for(const IntrospectedMethod* m = intro->signals; m->args; ++m)
{
xml << "<signal name=\"" << m->name << "\">";
xml << "\n\t\t<signal name=\"" << m->name << "\">";
for(const IntrospectedArgument* a = m->args; a->type; ++a)
{
@ -104,12 +104,22 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
xml << "/>";
}
xml << "</signal>";
xml << "\n\t\t</signal>";
}
xml << "</interface>";
xml << "\n\t</interface>";
}
}
const ObjectPathList nodes = ObjectAdaptor::child_nodes_from_prefix(path + '/');
ObjectPathList::const_iterator oni;
for(oni = nodes.begin(); oni != nodes.end(); ++oni)
{
xml << "\n\t<node name=\"" << (*oni) << "\"/>";
}
/* broken
const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/');
ObjectAdaptorPList::const_iterator oci;
@ -121,8 +131,9 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
xml << "<node name=\"" << name << "\"/>";
}
*/
xml << "</node>";
xml << "\n</node>";
ReturnMessage reply(call);
MessageIter wi = reply.writer();

View file

@ -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 )