summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Volz <andreas@frodo.mittelerde>2009-01-08 22:11:38 +0100
committerAndreas Volz <andreas@frodo.mittelerde>2009-01-08 22:11:38 +0100
commitafc679a47d2b6a97271847d03303c534e60ebf62 (patch)
tree6e9cc2cef38e7cdeea85d52729b73ee051636c56
parentd6e5ed5f9c8871e3668392785c85d2a4b85e6543 (diff)
downloaddbus-c++-afc679a47d2b6a97271847d03303c534e60ebf62.tar.gz
merge from fdo
-rw-r--r--examples/glib/dbus-browser.cpp3
-rw-r--r--examples/properties/props-server.cpp50
-rw-r--r--include/dbus-c++/dispatcher.h1
-rw-r--r--include/dbus-c++/glib-integration.h4
-rw-r--r--include/dbus-c++/interface.h4
-rw-r--r--include/dbus-c++/object.h2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/connection.cpp13
-rw-r--r--src/connection_p.h3
-rw-r--r--src/dispatcher.cpp21
-rw-r--r--src/glib-integration.cpp107
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)