From 4a69ad00119860acce3274bdd762ae9a4c627e24 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Wed, 8 Aug 2012 16:44:06 -0400 Subject: dbus-1/: fix watching for multiple sources When multiple sources are in use (ie: non-trivial profiles) then change monitoring needs to watch multiple D-Bus object paths. This involves sending multiple AddMatch requests and receiving multiple replies. The dbus-1 backend was only ever expecting to receive one reply, however (apparently never having been used with multiple sources). It freed its internal state object after the first reply, causing memory access errors on the subsequent replies. --- dbus-1/dconf-dbus-1.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/dbus-1/dconf-dbus-1.c b/dbus-1/dconf-dbus-1.c index 50dc0f8..64e02c4 100644 --- a/dbus-1/dconf-dbus-1.c +++ b/dbus-1/dconf-dbus-1.c @@ -440,6 +440,15 @@ dconf_dbus_client_scan_outstanding (DConfDBusClient *dcdbc, * * We just initially set it to 2, since these are the only two users. * That way we can skip having the ref() function. + * + * We also track the number of outstanding messages that we are waiting + * to see before assuming that the watch has been established. This is + * set to the number of messages sent and decremented for each incoming + * reply. When it hits zero, we do one single unref. + * + * We need to keep this number separate from the refcount due to the + * fact that we need to do some additional checking when the last reply + * arrives (see code below). */ typedef struct { @@ -449,6 +458,7 @@ typedef struct gpointer user_data; guint64 initial_state; gint ref_count; + gint n_messages; } Watch; @@ -555,6 +565,12 @@ add_match_done (DBusPendingCall *pending, else g_variant_unref (reply); /* it is just an empty tuple */ + /* There may be multiple messages to receive replies for. Make sure + * we have them all before proceeding. + */ + if (--watch->n_messages != 0) + return; + /* In the normal case we're done. * * There is a fleeting chance, however, that the database has changed @@ -576,9 +592,10 @@ dconf_dbus_client_subscribe (DConfDBusClient *dcdbc, { DConfEngineMessage dcem; Watch *watch; - + watch = watch_new (dcdbc, name, notify, user_data); dconf_engine_watch (dcdbc->engine, name, &dcem); + watch->n_messages = dcem.n_messages; dconf_dbus_client_send (dcdbc, &dcem, add_match_done, watch); dconf_engine_message_destroy (&dcem); } -- cgit v1.2.1