[gnome-contacts] Handle race condition in FakePersona conversion



commit 82a0aab0434804e954df5aeb63f58c1716a10ea7
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Aug 25 22:03:10 2011 +0200

    Handle race condition in FakePersona conversion
    
    If we get multiple requests to make real and set a property on
    a fake persona we queue them all up for when there is a real
    persona.

 src/contacts-contact-pane.vala |    3 ++-
 src/contacts-contact.vala      |   31 +++++++++++++++++++++++++------
 2 files changed, 27 insertions(+), 7 deletions(-)
---
diff --git a/src/contacts-contact-pane.vala b/src/contacts-contact-pane.vala
index 9aea2c1..2bbb829 100644
--- a/src/contacts-contact-pane.vala
+++ b/src/contacts-contact-pane.vala
@@ -360,7 +360,8 @@ public class Contacts.ContactPane : EventBox {
       fake.make_real_and_set.begin (property_name, detail_set, (obj, result) => {
 	  try {
 	    var p = fake.make_real_and_set.end (result);
-	    if (display_mode == DisplayMode.EDIT &&
+	    if (p != null &&
+		display_mode == DisplayMode.EDIT &&
 		editing_persona == editing_backup) {
 	      update_persona_buttons (fake.contact, p);
 	      editing_persona = p;
diff --git a/src/contacts-contact.vala b/src/contacts-contact.vala
index 274375d..99b50a5 100644
--- a/src/contacts-contact.vala
+++ b/src/contacts-contact.vala
@@ -883,6 +883,12 @@ public class Contacts.Contact : GLib.Object  {
 
 public class Contacts.FakePersona : Persona {
   public Contact contact;
+  private class PropVal {
+    public string property;
+    public Object value;
+  }
+  private ArrayList<PropVal> prop_vals;
+  private bool now_real;
 
   public static FakePersona? maybe_create_for (Contact contact) {
     var primary_persona = contact.find_primary_persona ();
@@ -905,12 +911,25 @@ public class Contacts.FakePersona : Persona {
       get { return this._writeable_properties; }
     }
 
-  public async Persona make_real_and_set (string property_name,
-					  void *value) throws GLib.Error {
-    Persona p;
-    p = yield contact.ensure_primary_persona ();
-    p.set (property_name, value);
-    return p;
+  public async Persona? make_real_and_set (string property,
+					   Object value) throws GLib.Error {
+    var v = new PropVal ();
+    v.property = property;
+    v.value = value;
+    if (prop_vals == null) {
+      prop_vals = new ArrayList<PropVal> ();
+      prop_vals.add (v);
+      Persona p = yield contact.ensure_primary_persona ();
+      foreach (var pv in prop_vals) {
+	p.set (pv.property, pv.value);
+      }
+      now_real = true;
+      return p;
+    } else {
+      assert (!now_real);
+      prop_vals.add (v);
+      return null;
+    }
   }
 
   public FakePersona (Contact contact, PersonaStore store) {



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