Bug 665039 — Crash in folks_backends_sw_backend_add_service
authorPhilip Withnall <philip@tecnocode.co.uk>
Tue, 6 Dec 2011 14:23:08 +0000 (14:23 +0000)
committerPhilip Withnall <philip@tecnocode.co.uk>
Tue, 6 Dec 2011 14:38:53 +0000 (14:38 +0000)
Hold a reference to the Sw.Backend while waiting for a SwClient async call
to finish in prepare().

Similar changes are made in Swf.PersonaStore to avoid potential bugs there.

Closes: bgo#665039

NEWS
backends/libsocialweb/lib/swf-persona-store.vala
backends/libsocialweb/sw-backend.vala

diff --git a/NEWS b/NEWS
index 9805051..f1b6778 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ Bugs fixed:
   in a single run
 * Bug 663889 — crash due to NameDetails which fail to guarantee
   non-null full-name/nickname
+* Bug 665039 — Crash in folks_backends_sw_backend_add_service
 
 Overview of changes from libfolks 0.6.4.1 to libfolks 0.6.5
 =============================================================
index 9058b6a..6557490 100644 (file)
@@ -212,25 +212,43 @@ public class Swf.PersonaStore : Folks.PersonaStore
         {
           if (!this._is_prepared)
             {
+              /* Take a reference to the PersonaStore while waiting for the
+               * async call to return. See: bgo#665039. */
+              this.ref ();
+
               this._service.get_static_capabilities (
                   (service, caps, error) =>
                     {
                       if (caps == null)
-                        return;
+                        {
+                          this.unref ();
+                          return;
+                        }
 
                       bool has_contacts = ClientService.has_cap (caps,
                           "has-contacts-query-iface");
                       if (!has_contacts)
-                        return;
+                        {
+                          this.unref ();
+                          return;
+                        }
+
                       var parameters = new HashTable<weak string, weak string>
                           (str_hash, str_equal);
+
+                      /* Take another ref for this async call. */
+                      this.ref ();
+
                       this._service.contacts_query_open_view
                           ("people", parameters, (query, contact_view) =>
                         {
                           /* The D-Bus call could return an error. In this
                            * case, contact_view is null */
                           if (contact_view == null)
-                            return;
+                            {
+                              this.unref ();
+                              return;
+                            }
 
                           contact_view.contacts_added.connect
                               (this.contacts_added_cb);
@@ -261,7 +279,11 @@ public class Swf.PersonaStore : Folks.PersonaStore
                           this.notify_property ("is-quiescent");
 
                           this._contact_view.start ();
+
+                          this.unref ();
                         });
+
+                      this.unref ();
                     });
             }
         }
index dcfc14b..9f78a67 100644 (file)
@@ -93,7 +93,12 @@ public class Folks.Backends.Sw.Backend : Folks.Backend
         {
           if (!this._is_prepared)
             {
-              this._client = new Client();
+              /* Hold a ref. on the Backend while we wait for the callback from
+               * this._client.get_services() to prevent the Backend being
+               * destroyed in the mean time. See: bgo#665039. */
+              this.ref ();
+
+              this._client = new Client ();
               this._client.get_services((client, services) =>
                 {
                   foreach (var service_name in services)
@@ -104,6 +109,8 @@ public class Folks.Backends.Sw.Backend : Folks.Backend
 
                   this._is_quiescent = true;
                   this.notify_property ("is-quiescent");
+
+                  this.unref ();
                 });
             }
         }