$OpenBSD: patch-folks_individual_vala,v 1.1 2013/12/08 10:43:21 ajacoutot Exp $

From c7318f12dede2d56c64b7e9cddc5a26b77c2c89a Mon Sep 17 00:00:00 2001
From: Philip Withnall <philip.withnall@collabora.co.uk>
Date: Wed, 20 Nov 2013 11:55:05 +0000
Subject: individual: Change an assertion into a warning and relax its conditions

From f00534294d7d52ac7e37dfaa075e3465b7755483 Mon Sep 17 00:00:00 2001
From: Philip Withnall <philip.withnall@collabora.co.uk>
Date: Wed, 20 Nov 2013 13:12:11 +0000
Subject: individual: Clean up how Personas are transferred between Individuals

--- folks/individual.vala.orig	Sun Dec  8 10:19:35 2013
+++ folks/individual.vala	Sun Dec  8 10:19:26 2013
@@ -1205,14 +1205,27 @@ public class Folks.Individual : Object,
 
   private void _persona_notify_cb (Object obj, ParamSpec ps)
     {
-      assert (obj is Persona);
-      assert (ps.name == "individual" || (obj as Persona).individual == this);
+      var persona = (Persona) obj;  /* will abort on failure */
 
+      /* It should not be possible for two Individuals to be simultaneously
+       * connected to the same Persona (as _connect_to_persona() will disconnect
+       * any previous Persona.individual), but warn (rather than asserting) just
+       * in case, since this is a critical code path. */
+      if (ps.name != "individual" &&
+          persona.individual != this &&
+          persona.individual != null)
+        {
+          warning ("Notification on property '%s' of Persona %p ('%s') where " +
+              "Persona.individual is %p but was expected to be %p.",
+              ps.name, persona, persona.uid, persona.individual, this);
+          return;
+        }
+
       foreach (var notifier in Individual._notifiers)
         {
           if (ps.name == notifier.property)
             {
-              notifier.notify (this, (!) (obj as Persona), ps);
+              notifier.notify (this, persona, ps);
               break;  /* assume all entries in notifiers are unique */
             }
         }
@@ -1888,6 +1901,13 @@ public class Folks.Individual : Object,
 
   private void _connect_to_persona (Persona persona)
     {
+      if (persona.individual != null)
+        {
+          /* Disconnect the previous Individual. This atomically avoids having
+           * two Individuals connected to the same Persona simultaneously. */
+          persona.individual._disconnect_from_persona (persona, this);
+        }
+
       persona.individual = this;
 
       /* We're interested in most, if not all, signals from a persona,
