From 6ab0492a6de58d62ed963a82c0924b3550b762e0 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Tue, 6 Dec 2011 14:23:08 +0000 Subject: [PATCH] =?utf8?q?Bug=20665039=20=E2=80=94=20Crash=20in=20folks=5F?= =?utf8?q?backends=5Fsw=5Fbackend=5Fadd=5Fservice?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 (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 (); }); } } -- 2.7.4