[dconf] engine: fix race in match rule adding



commit 54a490e4d9b5a788fa63011fb6ff73ad1c1ebf80
Author: Ryan Lortie <desrt desrt ca>
Date:   Fri Feb 21 20:04:39 2014 -0500

    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

 engine/dconf-engine.c |   18 +++++++++++-------
 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]