diff options
author | Andreas Volz <andreas@frodo.mittelerde> | 2009-01-08 22:11:38 +0100 |
---|---|---|
committer | Andreas Volz <andreas@frodo.mittelerde> | 2009-01-08 22:11:38 +0100 |
commit | afc679a47d2b6a97271847d03303c534e60ebf62 (patch) | |
tree | 6e9cc2cef38e7cdeea85d52729b73ee051636c56 | |
parent | d6e5ed5f9c8871e3668392785c85d2a4b85e6543 (diff) | |
download | dbus-c++-afc679a47d2b6a97271847d03303c534e60ebf62.tar.gz |
merge from fdo
-rw-r--r-- | examples/glib/dbus-browser.cpp | 3 | ||||
-rw-r--r-- | examples/properties/props-server.cpp | 50 | ||||
-rw-r--r-- | include/dbus-c++/dispatcher.h | 1 | ||||
-rw-r--r-- | include/dbus-c++/glib-integration.h | 4 | ||||
-rw-r--r-- | include/dbus-c++/interface.h | 4 | ||||
-rw-r--r-- | include/dbus-c++/object.h | 2 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/connection.cpp | 13 | ||||
-rw-r--r-- | src/connection_p.h | 3 | ||||
-rw-r--r-- | src/dispatcher.cpp | 21 | ||||
-rw-r--r-- | src/glib-integration.cpp | 107 |
11 files changed, 140 insertions, 70 deletions
diff --git a/examples/glib/dbus-browser.cpp b/examples/glib/dbus-browser.cpp index 77a3a22..382d07f 100644 --- a/examples/glib/dbus-browser.cpp +++ b/examples/glib/dbus-browser.cpp @@ -2,12 +2,9 @@ #include <xml.h> #include <iostream> -#include <vector> using namespace std; -typedef vector <string> Names; - static const char *DBUS_SERVER_NAME = "org.freedesktop.DBus"; static const char *DBUS_SERVER_PATH = "/org/freedesktop/DBus"; diff --git a/examples/properties/props-server.cpp b/examples/properties/props-server.cpp deleted file mode 100644 index 4c9999d..0000000 --- a/examples/properties/props-server.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "props-server.h" -#include <signal.h> - -static const char *PROPS_SERVER_NAME = "org.freedesktop.DBus.Examples.Properties"; -static const char *PROPS_SERVER_PATH = "/org/freedesktop/DBus/Examples/Properties"; - -PropsServer::PropsServer(DBus::Connection &connection) -: DBus::ObjectAdaptor(connection, PROPS_SERVER_PATH) -{ - Version = 1; - Message = "default message"; -} - -void PropsServer::on_set_property - (DBus::InterfaceAdaptor &interface, const std::string &property, const DBus::Variant &value) -{ - if (property == "Message") - { - std::string msg = value; - this->MessageChanged(msg); - } -} - -DBus::BusDispatcher dispatcher; - -void niam(int sig) -{ - dispatcher.leave(); -} - -int main() -{ - signal(SIGTERM, niam); - signal(SIGINT, niam); - - DBus::default_dispatcher = &dispatcher; - - DBus::Connection conn = DBus::Connection::SessionBus(); - conn.request_name(PROPS_SERVER_NAME); - - PropsServer server(conn); - - dispatcher.enter(); - - return 0; -} diff --git a/include/dbus-c++/dispatcher.h b/include/dbus-c++/dispatcher.h index 2287215..10179ff 100644 --- a/include/dbus-c++/dispatcher.h +++ b/include/dbus-c++/dispatcher.h @@ -157,6 +157,7 @@ public: void queue_connection(Connection::Private *); void dispatch_pending(); + bool has_something_to_dispatch(); virtual void enter() = 0; diff --git a/include/dbus-c++/glib-integration.h b/include/dbus-c++/glib-integration.h index 7a0dbf0..76eae5e 100644 --- a/include/dbus-c++/glib-integration.h +++ b/include/dbus-c++/glib-integration.h @@ -90,7 +90,8 @@ class DXXAPI BusDispatcher : public Dispatcher { public: - BusDispatcher() : _ctx(NULL), _priority(G_PRIORITY_DEFAULT) {} + BusDispatcher(); + ~BusDispatcher(); void attach(GMainContext *); @@ -112,6 +113,7 @@ private: GMainContext *_ctx; int _priority; + GSource *_source; }; } /* namespace Glib */ diff --git a/include/dbus-c++/interface.h b/include/dbus-c++/interface.h index 0c5c2ac..86c8d18 100644 --- a/include/dbus-c++/interface.h +++ b/include/dbus-c++/interface.h @@ -95,8 +95,8 @@ protected: {} virtual Message _invoke_method(CallMessage &) = 0; - - virtual bool _invoke_method_noreply(CallMessage &call) = 0; + + virtual bool _invoke_method_noreply(CallMessage &call) = 0; InterfaceProxyTable _interfaces; }; diff --git a/include/dbus-c++/object.h b/include/dbus-c++/object.h index 9d81d9d..962bf77 100644 --- a/include/dbus-c++/object.h +++ b/include/dbus-c++/object.h @@ -202,7 +202,7 @@ private: Message _invoke_method(CallMessage &); - bool _invoke_method_noreply(CallMessage &call); + bool _invoke_method_noreply(CallMessage &call); bool handle_message(const Message &); diff --git a/src/Makefile.am b/src/Makefile.am index fc7f7ad..09ddc5b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = \ $(dbus_CFLAGS) \ $(glib_CFLAGS) \ - $(ecore_CFLAGS) \ + $(ecore_CFLAGS) \ $(PRIVATE_CFLAGS) \ -I$(top_srcdir)/include \ -I$(top_builddir)/include diff --git a/src/connection.cpp b/src/connection.cpp index 674bb51..4244d9a 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -88,7 +88,7 @@ void Connection::Private::init() this, &Connection::Private::disconn_filter_function ); - dbus_connection_add_filter(conn, message_filter_stub, &disconn_filter, NULL); + dbus_connection_add_filter(conn, message_filter_stub, &disconn_filter, NULL); // TODO: some assert at least dbus_connection_set_dispatch_status_function(conn, dispatch_status_stub, this, 0); dbus_connection_set_exit_on_disconnect(conn, false); //why was this set to true?? @@ -175,6 +175,17 @@ bool Connection::Private::disconn_filter_function(const Message &msg) return false; } +DBusDispatchStatus Connection::Private::dispatch_status() +{ + return dbus_connection_get_dispatch_status(conn); +} + +bool Connection::Private::has_something_to_dispatch() +{ + return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS; +} + + Connection Connection::SystemBus() { return Connection(new Private(DBUS_BUS_SYSTEM)); diff --git a/src/connection_p.h b/src/connection_p.h index 408bd9e..a6ea96c 100644 --- a/src/connection_p.h +++ b/src/connection_p.h @@ -63,6 +63,9 @@ struct DXXAPILOCAL Connection::Private void init(); + DBusDispatchStatus dispatch_status(); + bool has_something_to_dispatch(); + static void dispatch_status_stub(DBusConnection *, DBusDispatchStatus, void *); static DBusHandlerResult message_filter_stub(DBusConnection *, DBusMessage *, void *); diff --git a/src/dispatcher.cpp b/src/dispatcher.cpp index c4ba299..2da4e86 100644 --- a/src/dispatcher.cpp +++ b/src/dispatcher.cpp @@ -155,10 +155,29 @@ void Dispatcher::queue_connection(Connection::Private *cp) _mutex_p.unlock(); } + +bool Dispatcher::has_something_to_dispatch() +{ + _mutex_p.lock(); + bool has_something = false; + for(Connection::PrivatePList::iterator it = _pending_queue.begin(); + it != _pending_queue.end() && !has_something; + ++it) + { + has_something = (*it)->has_something_to_dispatch(); + } + + _mutex_p.unlock(); + return has_something; +} + + void Dispatcher::dispatch_pending() { _mutex_p.lock(); + // SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things... + while (_pending_queue.size() > 0) { Connection::PrivatePList::iterator i, j; @@ -185,7 +204,7 @@ void DBus::_init_threading() #ifdef DBUS_HAS_THREADS_INIT_DEFAULT dbus_threads_init_default(); #else - debug_log("Thread support is not enabled! Your D-Bus version is too old!"); + debug_log("Thread support is not enabled! Your D-Bus version is too old!"); #endif//DBUS_HAS_THREADS_INIT_DEFAULT } diff --git a/src/glib-integration.cpp b/src/glib-integration.cpp index e1f8d05..491c950 100644 --- a/src/glib-integration.cpp +++ b/src/glib-integration.cpp @@ -31,9 +31,10 @@ using namespace DBus; Glib::BusTimeout::BusTimeout(Timeout::Internal *ti, GMainContext *ctx, int priority) -: Timeout(ti), _ctx(ctx), _priority(priority) +: Timeout(ti), _ctx(ctx), _priority(priority), _source(NULL) { - _enable(); + if (Timeout::enabled()) + _enable(); } Glib::BusTimeout::~BusTimeout() @@ -60,6 +61,9 @@ gboolean Glib::BusTimeout::timeout_handler(gpointer data) void Glib::BusTimeout::_enable() { + if (_source) + _disable(); // be sane + _source = g_timeout_source_new(Timeout::interval()); g_source_set_priority(_source, _priority); g_source_set_callback(_source, timeout_handler, this, NULL); @@ -68,7 +72,11 @@ void Glib::BusTimeout::_enable() void Glib::BusTimeout::_disable() { - g_source_destroy(_source); + if (_source) + { + g_source_destroy(_source); + _source = NULL; + } } struct BusSource @@ -79,7 +87,7 @@ struct BusSource static gboolean watch_prepare(GSource *source, gint *timeout) { -// debug_log("glib: watch_prepare"); + //debug_log("glib: watch_prepare"); *timeout = -1; return FALSE; @@ -87,7 +95,7 @@ static gboolean watch_prepare(GSource *source, gint *timeout) static gboolean watch_check(GSource *source) { -// debug_log("glib: watch_check"); + //debug_log("glib: watch_check"); BusSource *io = (BusSource *)source; return io->poll.revents ? TRUE : FALSE; @@ -98,7 +106,6 @@ static gboolean watch_dispatch(GSource *source, GSourceFunc callback, gpointer d debug_log("glib: watch_dispatch"); gboolean cb = callback(data); - DBus::default_dispatcher->dispatch_pending(); //TODO: won't work in case of multiple dispatchers return cb; } @@ -110,9 +117,10 @@ static GSourceFuncs watch_funcs = { }; Glib::BusWatch::BusWatch(Watch::Internal *wi, GMainContext *ctx, int priority) -: Watch(wi), _ctx(ctx), _priority(priority) +: Watch(wi), _ctx(ctx), _priority(priority), _source(NULL) { - _enable(); + if (Watch::enabled()) + _enable(); } Glib::BusWatch::~BusWatch() @@ -151,6 +159,8 @@ gboolean Glib::BusWatch::watch_handler(gpointer data) void Glib::BusWatch::_enable() { + if (_source) + _disable(); // be sane _source = g_source_new(&watch_funcs, sizeof(BusSource)); g_source_set_priority(_source, _priority); g_source_set_callback(_source, watch_handler, this, NULL); @@ -160,8 +170,8 @@ void Glib::BusWatch::_enable() if (flags &DBUS_WATCH_READABLE) condition |= G_IO_IN; -// if (flags &DBUS_WATCH_WRITABLE) -// condition |= G_IO_OUT; + if (flags &DBUS_WATCH_WRITABLE) + condition |= G_IO_OUT; if (flags &DBUS_WATCH_ERROR) condition |= G_IO_ERR; if (flags &DBUS_WATCH_HANGUP) @@ -178,14 +188,91 @@ void Glib::BusWatch::_enable() void Glib::BusWatch::_disable() { + if (!_source) + return; GPollFD *poll = &(((BusSource *)_source)->poll); g_source_remove_poll(_source, poll); g_source_destroy(_source); + _source = NULL; +} + +/* + * We need this on top of the IO handlers, because sometimes + * there are messages to dispatch queued up but no IO pending. + * (fixes also a previous problem of code not working in case of multiple dispatchers) +*/ +struct DispatcherSource +{ + GSource source; + Dispatcher *dispatcher; +}; + + +static gboolean dispatcher_prepare(GSource *source, gint *timeout) +{ + Dispatcher *dispatcher = ((DispatcherSource*)source)->dispatcher; + + *timeout = -1; + + return dispatcher->has_something_to_dispatch()? TRUE:FALSE; +} + +static gboolean dispatcher_check(GSource *source) +{ + return FALSE; +} + +static gboolean +dispatcher_dispatch(GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + Dispatcher *dispatcher = ((DispatcherSource*)source)->dispatcher; + + dispatcher->dispatch_pending(); + return TRUE; +} + +static const GSourceFuncs dispatcher_funcs = { + dispatcher_prepare, + dispatcher_check, + dispatcher_dispatch, + NULL +}; + +Glib::BusDispatcher::BusDispatcher() +: _ctx(NULL), _priority(G_PRIORITY_DEFAULT), _source(NULL) +{ +} + +Glib::BusDispatcher::~BusDispatcher() +{ + if (_source) + { + GSource *temp = _source; + _source = NULL; + + g_source_destroy (temp); + g_source_unref (temp); + } + + if (_ctx) + g_main_context_unref(_ctx); } void Glib::BusDispatcher::attach(GMainContext *ctx) { + g_assert(_ctx == NULL); // just to be sane + _ctx = ctx ? ctx : g_main_context_default(); + g_main_context_ref(_ctx); + + // create the source for dispatching messages + _source = g_source_new((GSourceFuncs *) &dispatcher_funcs, + sizeof(DispatcherSource)); + + ((DispatcherSource*)_source)->dispatcher = this; + g_source_attach (_source, _ctx); } Timeout *Glib::BusDispatcher::add_timeout(Timeout::Internal *wi) |