[folks] bluez: Eliminate a reflexive reference in Bluez.PersonaStore



commit c83bddc2bf5a31c3e864091b92ae00b39afef535
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Wed Nov 13 16:06:34 2013 +0000

    bluez: Eliminate a reflexive reference in Bluez.PersonaStore
    
    Since the persona store is always scheduling the next update, it always
    holds a reference to itself in the timeout closure, which is
    unavoidable. Add a cancel_updates() internal method which can be called
    by the Backend to break this reflexive reference and allow the store to
    be finalised.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=711827

 backends/bluez/bluez-backend.vala       |    4 ++++
 backends/bluez/bluez-persona-store.vala |   29 ++++++++++++++++++++++-------
 2 files changed, 26 insertions(+), 7 deletions(-)
---
diff --git a/backends/bluez/bluez-backend.vala b/backends/bluez/bluez-backend.vala
index 08a7ebc..9032c43 100644
--- a/backends/bluez/bluez-backend.vala
+++ b/backends/bluez/bluez-backend.vala
@@ -388,6 +388,10 @@ public class Folks.Backends.BlueZ.Backend : Folks.Backend
     {
       store.removed.disconnect (this._persona_store_removed_cb);
 
+      /* Cancel all ongoing activity in the store and, critically, eliminate
+       * the reflexive reference it holds. */
+      store.cancel_updates ();
+
       this.persona_store_removed (store);
 
       this._persona_stores.unset (store.id);
diff --git a/backends/bluez/bluez-persona-store.vala b/backends/bluez/bluez-persona-store.vala
index a846c8f..1af1500 100644
--- a/backends/bluez/bluez-persona-store.vala
+++ b/backends/bluez/bluez-persona-store.vala
@@ -460,13 +460,7 @@ public class Folks.Backends.BlueZ.PersonaStore : Folks.PersonaStore
               this._device.address);
 
           /* Cancel any ongoing or scheduled transfers. */
-          if (this._update_contacts_cancellable != null)
-              this._update_contacts_cancellable.cancel ();
-          if (this._update_contacts_id != 0)
-            {
-              Source.remove (this._update_contacts_id);
-              this._update_contacts_id = 0;
-            }
+          this.cancel_updates ();
         }
     }
 
@@ -932,6 +926,27 @@ public class Folks.Backends.BlueZ.PersonaStore : Folks.PersonaStore
     }
 
   /**
+   * Cancel ongoing and scheduled updates from the device.
+   *
+   * This doesn't remove the store, but does cancel all ongoing updates and
+   * future scheduled updates, in preparation for removing the store. This is
+   * necessary to avoid the store maintaining a reference to itself (through the
+   * closure for the next scheduled update) and thus never being finalised.
+   *
+   * @since UNRELEASED
+   */
+  internal void cancel_updates ()
+    {
+      if (this._update_contacts_cancellable != null)
+          this._update_contacts_cancellable.cancel ();
+      if (this._update_contacts_id != 0)
+        {
+          Source.remove (this._update_contacts_id);
+          this._update_contacts_id = 0;
+        }
+    }
+
+  /**
    * { inheritDoc}
    *
    * @since 0.9.6


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