[folks] eds: Handle removed contacts in objects-added signal handler



commit 5a58b7b07a69663a0feba14bfc4e51623750fea5
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Sat Mar 28 15:36:01 2015 +0000

    eds: Handle removed contacts in objects-added signal handler
    
    This is a very unlikely situation, but it may be possible for a contact
    with the same UID as an existing one in the store to be received from
    the server in an objects-added signal. If so, folks' internal state
    would previously be corrupted. Fix this by signalling removal of the
    previous persona before adding the new one for that UID.

 backends/eds/lib/edsf-persona-store.vala |   29 +++++++++++++++++++++++------
 1 files changed, 23 insertions(+), 6 deletions(-)
---
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index c68ff75..451fcd4 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -2508,7 +2508,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
 
   private bool _contacts_added_idle (Gee.List<E.Contact> contacts)
     {
-      HashSet<Persona> added_personas;
+      HashSet<Persona> added_personas, removed_personas;
 
       /* If the persona store hasn't yet reached quiescence, queue up the
        * personas and emit a notification about them later; see
@@ -2528,20 +2528,37 @@ public class Edsf.PersonaStore : Folks.PersonaStore
           added_personas = new HashSet<Persona> ();
         }
 
+      removed_personas = new HashSet<Persona> ();
+
       foreach (E.Contact c in contacts)
         {
           var iid = Edsf.Persona.build_iid_from_contact (this.id, c);
-          if (this._personas.has_key (iid) == false)
+          var old_persona = this._personas.get (iid);
+          var new_persona = new Persona (this, c);
+
+          if (old_persona != null)
             {
-              var persona = new Persona (this, c);
-              this._personas.set (persona.iid, persona);
-              added_personas.add (persona);
+              debug ("Removing old persona %p from contact %s.",
+                  old_persona, iid);
+              removed_personas.add (old_persona);
+
+              /* Handle the case where a contact is removed before the persona
+               * store has reached quiescence. */
+              if (this._pending_personas != null)
+                {
+                  this._pending_personas.remove (old_persona);
+                }
             }
+
+          debug ("Adding persona %p from contact %s.", new_persona, iid);
+
+          this._personas.set (new_persona.iid, new_persona);
+          added_personas.add (new_persona);
         }
 
       if (added_personas.size > 0 && this._is_quiescent == true)
         {
-          this._emit_personas_changed (added_personas, null);
+          this._emit_personas_changed (added_personas, removed_personas);
         }
 
       /* Done. */


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