summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2014-02-21 20:04:39 -0500
committerRyan Lortie <desrt@desrt.ca>2014-02-21 20:07:00 -0500
commit54a490e4d9b5a788fa63011fb6ff73ad1c1ebf80 (patch)
tree20ea055d139e858ef071367ae05bcb11cfc06c44 /engine
parent363eda5b0572eac73d5514b4f3dbd0ab7e250b4d (diff)
downloaddconf-54a490e4d9b5a788fa63011fb6ff73ad1c1ebf80.tar.gz
engine: fix race in match rule adding
Due to the usual way async in dconf works, we can start getting replies immediately (without returning to the mainloop). For this reason, we must be sure that we do not modify the OutstandingWatch structure at any point after we've issued even one call because the results may already be coming in. For this reason, we must add up the 'pending' count in a separate loop run before we start making the calls. https://bugzilla.gnome.org/show_bug.cgi?id=724929
Diffstat (limited to 'engine')
-rw-r--r--engine/dconf-engine.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/engine/dconf-engine.c b/engine/dconf-engine.c
index 864e8e2..57bce96 100644
--- a/engine/dconf-engine.c
+++ b/engine/dconf-engine.c
@@ -814,15 +814,19 @@ dconf_engine_watch_fast (DConfEngine *engine,
G_VARIANT_TYPE_UNIT, sizeof (OutstandingWatch));
ow->state = dconf_engine_get_state (engine);
+ /* We start getting async calls returned as soon as we start dispatching them,
+ * so we must not touch the 'ow' struct after we send the first one.
+ */
for (i = 0; i < engine->n_sources; i++)
if (engine->sources[i]->bus_type)
- {
- dconf_engine_dbus_call_async_func (engine->sources[i]->bus_type, "org.freedesktop.DBus",
- "/org/freedesktop/DBus", "org.freedesktop.DBus", "AddMatch",
- dconf_engine_make_match_rule (engine->sources[i], path),
- &ow->handle, NULL);
- ow->pending++;
- }
+ ow->pending++;
+
+ for (i = 0; i < engine->n_sources; i++)
+ if (engine->sources[i]->bus_type)
+ dconf_engine_dbus_call_async_func (engine->sources[i]->bus_type, "org.freedesktop.DBus",
+ "/org/freedesktop/DBus", "org.freedesktop.DBus", "AddMatch",
+ dconf_engine_make_match_rule (engine->sources[i], path),
+ &ow->handle, NULL);
}
void