=?utf-8?q?=5Bfolks=5D_Bug_665039_=E2=80=94_Crash_in_folks=5Fbackends=5Fsw?= =?utf-8?q?=5Fbackend=5Fadd=5Fservice?=



commit 6ab0492a6de58d62ed963a82c0924b3550b762e0
Author: Philip Withnall <philip tecnocode co uk>
Date:   Tue Dec 6 14:23:08 2011 +0000

    Bug 665039 â Crash in folks_backends_sw_backend_add_service
    
    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                                             |    1 +
 backends/libsocialweb/lib/swf-persona-store.vala |   28 +++++++++++++++++++--
 backends/libsocialweb/sw-backend.vala            |    9 ++++++-
 3 files changed, 34 insertions(+), 4 deletions(-)
---
diff --git a/NEWS b/NEWS
index 9805051..f1b6778 100644
--- 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
 =============================================================
diff --git a/backends/libsocialweb/lib/swf-persona-store.vala b/backends/libsocialweb/lib/swf-persona-store.vala
index 9058b6a..6557490 100644
--- a/backends/libsocialweb/lib/swf-persona-store.vala
+++ b/backends/libsocialweb/lib/swf-persona-store.vala
@@ -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 ();
                     });
             }
         }
diff --git a/backends/libsocialweb/sw-backend.vala b/backends/libsocialweb/sw-backend.vala
index dcfc14b..9f78a67 100644
--- a/backends/libsocialweb/sw-backend.vala
+++ b/backends/libsocialweb/sw-backend.vala
@@ -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 ();
                 });
             }
         }



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