kdbus: fix race-condition in GDBusNameWatching component 41/94541/3 accepted/tizen/common/20161114.170921 accepted/tizen/ivi/20161114.005113 accepted/tizen/mobile/20161114.004933 accepted/tizen/tv/20161114.005004 accepted/tizen/wearable/20161114.005043 submit/tizen/20161111.051722
authorLukasz Skalski <l.skalski@samsung.com>
Mon, 31 Oct 2016 10:49:11 +0000 (11:49 +0100)
committerAdrian Szyndela <adrian.s@samsung.com>
Thu, 3 Nov 2016 11:37:22 +0000 (12:37 +0100)
To avoid race-condition between GetNameOwner replay and
NameOwnerChanged signal in GDBusNameWatching component,
let's always use GetNameOwner sync call on kdbus bus.

Change-Id: Iebb780737d753d989a7d928f65d433d86d79284a

gio/gdbusnamewatching.c

index 07713db..c35485a 100644 (file)
@@ -322,6 +322,23 @@ on_name_owner_changed (GDBusConnection *connection,
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
+handle_new_name_owner (Client *client,
+                       const gchar *name_owner)
+{
+  if (name_owner != NULL)
+    {
+      g_warn_if_fail (client->name_owner == NULL);
+      client->name_owner = name_owner;
+      call_appeared_handler (client);
+    }
+  else
+    {
+      call_vanished_handler (client, FALSE);
+    }
+  client->initialized = TRUE;
+}
+
+static void
 get_name_owner_cb (GObject      *source_object,
                    GAsyncResult *res,
                    gpointer      user_data)
@@ -341,18 +358,7 @@ get_name_owner_cb (GObject      *source_object,
       g_variant_get (result, "(&s)", &name_owner);
     }
 
-  if (name_owner != NULL)
-    {
-      g_warn_if_fail (client->name_owner == NULL);
-      client->name_owner = g_strdup (name_owner);
-      call_appeared_handler (client);
-    }
-  else
-    {
-      call_vanished_handler (client, FALSE);
-    }
-
-  client->initialized = TRUE;
+  handle_new_name_owner (client, g_strdup (name_owner));
 
   if (result != NULL)
     g_variant_unref (result);
@@ -472,8 +478,22 @@ has_connection (Client *client)
     }
   else
     {
-      /* check owner */
-      invoke_get_name_owner (client);
+      /* check owner - to avoid race-condition between GetNameOwner reply and
+         NameOwnerChanged signal let's use GetNameOwner sync call on kdbus bus */
+      if (_g_dbus_connection_is_kdbus (client->connection))
+        {
+          gchar *name_owner;
+
+          name_owner = g_dbus_get_name_owner (client->connection,
+                                              client->name,
+                                              NULL);
+
+          handle_new_name_owner (client, name_owner);
+        }
+      else
+        {
+          invoke_get_name_owner (client);
+        }
     }
 }