From 25cf05ff36b63330063d065b6b1d40caaba9a835 Mon Sep 17 00:00:00 2001 From: Red1 Date: Mon, 12 Jan 2009 09:45:44 +0000 Subject: [PATCH] xml2cpp Bug fix : problem in type generation with complex array feature : Add nonblock function for each method in the proxy generation dispatcher/connection feature: Add constructor to create a connection passing a dispatcher (instead of creating a connection with default dispatcher and use setup after) Add fd to allow dispatcher to leave directly when leave method is called (instead of waiting for the timeout on the select) --- include/dbus-c++/connection.h | 11 +++-- include/dbus-c++/eventloop-integration.h | 11 ++++- include/dbus-c++/eventloop.h | 1 + src/connection.cpp | 16 ++++---- src/eventloop-integration.cpp | 3 + src/eventloop.cpp | 15 +++++++ tools/xml2cpp.cpp | 67 +++++++++++++++++++++++++---- 7 files changed, 101 insertions(+), 23 deletions(-) diff --git a/include/dbus-c++/connection.h b/include/dbus-c++/connection.h index 5cf1ae0..360efe0 100644 --- a/include/dbus-c++/connection.h +++ b/include/dbus-c++/connection.h @@ -44,21 +44,24 @@ typedef std::list ConnectionList; class ObjectAdaptor; class Dispatcher; +extern DXXAPI Dispatcher* default_dispatcher; + + class DXXAPI Connection { public: - static Connection SystemBus(); + static Connection SystemBus(Dispatcher* dispatcher = default_dispatcher ); - static Connection SessionBus(); + static Connection SessionBus(Dispatcher* dispatcher = default_dispatcher ); - static Connection ActivationBus(); + static Connection ActivationBus(Dispatcher* dispatcher = default_dispatcher ); struct Private; typedef std::list PrivatePList; - Connection( Private* ); + Connection(Private *, Dispatcher * dispatcher = default_dispatcher); Connection( const char* address, bool priv = true ); diff --git a/include/dbus-c++/eventloop-integration.h b/include/dbus-c++/eventloop-integration.h index 1bae382..583c1fb 100644 --- a/include/dbus-c++/eventloop-integration.h +++ b/include/dbus-c++/eventloop-integration.h @@ -60,8 +60,17 @@ 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) + pipe(_pipe); + _fdunlock[0] = _pipe[0]; + _fdunlock[1] = _pipe[1]; + + } ~BusDispatcher() {} diff --git a/include/dbus-c++/eventloop.h b/include/dbus-c++/eventloop.h index f7d0f6d..65fd7f6 100644 --- a/include/dbus-c++/eventloop.h +++ b/include/dbus-c++/eventloop.h @@ -149,6 +149,7 @@ public: virtual void dispatch(); + int _fdunlock[2]; private: DefaultMutex _mutex_t; diff --git a/src/connection.cpp b/src/connection.cpp index 4244d9a..880efb9 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -186,19 +186,19 @@ bool Connection::Private::has_something_to_dispatch() } -Connection Connection::SystemBus() +Connection Connection::SystemBus(Dispatcher* dispatcher ) { - return Connection(new Private(DBUS_BUS_SYSTEM)); + return Connection(new Private(DBUS_BUS_SYSTEM),dispatcher); } -Connection Connection::SessionBus() +Connection Connection::SessionBus(Dispatcher* dispatcher ) { - return Connection(new Private(DBUS_BUS_SESSION)); + return Connection(new Private(DBUS_BUS_SESSION),dispatcher); } -Connection Connection::ActivationBus() +Connection Connection::ActivationBus(Dispatcher* dispatcher ) { - return Connection(new Private(DBUS_BUS_STARTER)); + return Connection(new Private(DBUS_BUS_STARTER),dispatcher); } Connection::Connection(const char *address, bool priv) @@ -217,10 +217,10 @@ Connection::Connection(const char *address, bool priv) debug_log("connected to %s", address); } -Connection::Connection(Connection::Private *p) +Connection::Connection( Connection::Private* p ,Dispatcher* dispatcher ) : _pvt(p) { - setup(default_dispatcher); + setup(dispatcher); } Connection::Connection(const Connection &c) diff --git a/src/eventloop-integration.cpp b/src/eventloop-integration.cpp index ed0cc23..ea124af 100644 --- a/src/eventloop-integration.cpp +++ b/src/eventloop-integration.cpp @@ -85,6 +85,9 @@ void BusDispatcher::enter() void BusDispatcher::leave() { _running = false; + write(_fdunlock[1],"exit",strlen("exit")); + close(_fdunlock[1]); + close(_fdunlock[0]); } void BusDispatcher::do_iteration() diff --git a/src/eventloop.cpp b/src/eventloop.cpp index 7fac42c..73311f2 100644 --- a/src/eventloop.cpp +++ b/src/eventloop.cpp @@ -136,6 +136,9 @@ void DefaultMainLoop::dispatch() int nfd = _watches.size(); + if(_fdunlock) + nfd=nfd+2; + pollfd fds[nfd]; DefaultWatches::iterator wi = _watches.begin(); @@ -151,6 +154,18 @@ void DefaultMainLoop::dispatch() ++nfd; } } + + if(_fdunlock){ + fds[nfd].fd = _fdunlock[0]; + fds[nfd].events = POLLIN | POLLOUT | POLLPRI ; + fds[nfd].revents = 0; + + nfd++; + fds[nfd].fd = _fdunlock[1]; + fds[nfd].events = POLLIN | POLLOUT | POLLPRI ; + fds[nfd].revents = 0; + } + _mutex_w.unlock(); int wait_min = 10000; diff --git a/tools/xml2cpp.cpp b/tools/xml2cpp.cpp index 45c8dde..3fd6ed1 100644 --- a/tools/xml2cpp.cpp +++ b/tools/xml2cpp.cpp @@ -139,16 +139,53 @@ void _parse_signature(const string &signature, string &type, unsigned int &i) type += atom; type += ", "; ++i; + + _parse_signature(signature, type, i); + type += " >"; + + break; + } + case '(': + { + type += "std::vector< ::DBus::Struct< "; + + _parse_signature(signature, type, ++i); + + if (signature[i] != ')') + { + cerr << "invalid signature \"" << signature << "\"" << endl; + exit(-1); + } + + type += " > >"; + + if((i+1) < signature.length() && + signature[i+1] != ')' && signature[i+1] != '}') + { + type += ", "; + } break; } default: { type += "std::vector< "; - break; + const char* atom = atomic_type_to_string(signature[i++]); + if(!atom) + { + cerr << "invalid signature \"" << signature << "\"" << endl; + exit(-1); + } + type += atom; + + type += " >"; + + if((i+1) < signature.length() && + signature[i+1] != ')' && signature[i+1] != '}') + { + type += ", "; + } } } - _parse_signature(signature, type, i); - type += " >"; continue; } case '(': @@ -157,7 +194,8 @@ void _parse_signature(const string &signature, string &type, unsigned int &i) ++i; _parse_signature(signature, type, i); type += " >"; - if (signature[i+1]) + if((i+1) < signature.length() && + signature[i+1] != ')' && signature[i+1] != '}') { type += ", "; } @@ -345,6 +383,7 @@ void generate_proxy(Xml::Document &doc, const char *filename) << tab << "/* methods exported by this interface," << endl << tab << " * this functions will invoke the corresponding methods on the remote objects" << endl << tab << " */" << endl; + for(int my_i=0; my_i<2;my_i++){ for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi) { @@ -353,7 +392,7 @@ void generate_proxy(Xml::Document &doc, const char *filename) Xml::Nodes args_in = args.select("direction","in"); Xml::Nodes args_out = args.select("direction","out"); - if (args_out.size() == 0 || args_out.size() > 1) + if (args_out.size() == 0 || args_out.size() > 1 || my_i!=0 ) { file << tab << "void "; } @@ -361,8 +400,11 @@ void generate_proxy(Xml::Document &doc, const char *filename) { file << tab << signature_to_type(args_out.front()->get("type")) << " "; } - + + if(my_i==0) file << method.get("name") << "("; + else + file << method.get("name") << "ASync( "; unsigned int i = 0; for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i) @@ -419,24 +461,27 @@ void generate_proxy(Xml::Document &doc, const char *filename) else file << tab << tab << "wi << argin" << j << ";" << endl; } - + if(my_i==0) file << tab << tab << "call.member(\"" << method.get("name") << "\");" << endl << tab << tab << "::DBus::Message ret = invoke_method(call);" << endl; + else + file << tab << tab << "call.member(\"" << method.get("name") << "\");" << endl + << tab << tab << "invoke_method_noreply(call);" << endl; - if (args_out.size() > 0) + if (args_out.size() > 0 && my_i==0) { file << tab << tab << "::DBus::MessageIter ri = ret.reader();" << endl << endl; } - if (args_out.size() == 1) + if (args_out.size() == 1&& my_i==0 ) { file << tab << tab << signature_to_type(args_out.front()->get("type")) << " argout;" << endl; file << tab << tab << "ri >> argout;" << endl; file << tab << tab << "return argout;" << endl; } - else if (args_out.size() > 1) + else if (args_out.size() > 1 && my_i==0) { unsigned int i = 0; for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i) @@ -455,6 +500,8 @@ void generate_proxy(Xml::Document &doc, const char *filename) << endl; } + } + file << endl << "public:" << endl << endl -- 1.5.2.5