[evolution-data-server] ESource: Suppress "changed" emissions during initialization.



commit 7953a296d409dc4b741a35bb0707f167eb6864ca
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Aug 21 13:38:17 2012 -0400

    ESource: Suppress "changed" emissions during initialization.
    
    If an ESource is being instantiated from a worker thread, the change
    notifications can possibly be emitted from callbacks on the ESource's
    GMainContext before the ESource is fully initialized, which can break
    invariants like "all ESources have a non-NULL UID string".
    
    This commit suppresses those change notifications until the ESource
    instance is fully initialized.

 libedataserver/e-source.c |   28 +++++++++++++++++++---------
 1 files changed, 19 insertions(+), 9 deletions(-)
---
diff --git a/libedataserver/e-source.c b/libedataserver/e-source.c
index 219b4cf..1ed8d25 100644
--- a/libedataserver/e-source.c
+++ b/libedataserver/e-source.c
@@ -132,6 +132,7 @@ struct _ESourcePrivate {
 	GHashTable *extensions;
 
 	gboolean enabled;
+	gboolean initialized;
 };
 
 struct _AsyncContext {
@@ -665,6 +666,13 @@ source_idle_changed_cb (gpointer user_data)
 {
 	ESource *source = E_SOURCE (user_data);
 
+	/* If the ESource is still initializing itself in a different
+	 * thread, skip the signal emission and try again on the next
+	 * main loop iteration.  This is a busy wait but it should be
+	 * a very short wait. */
+	if (!source->priv->initialized)
+		return TRUE;
+
 	g_mutex_lock (source->priv->changed_lock);
 	if (source->priv->changed != NULL) {
 		g_source_unref (source->priv->changed);
@@ -1303,15 +1311,6 @@ source_initable_init (GInitable *initable,
 
 		success = source_parse_dbus_data (source, error);
 
-		/* Avoid a spurious "changed" emission. */
-		g_mutex_lock (source->priv->changed_lock);
-		if (source->priv->changed != NULL) {
-			g_source_destroy (source->priv->changed);
-			g_source_unref (source->priv->changed);
-			source->priv->changed = NULL;
-		}
-		g_mutex_unlock (source->priv->changed_lock);
-
 		g_object_unref (dbus_source);
 
 	/* No D-Bus object implies we're configuring a new source,
@@ -1320,6 +1319,17 @@ source_initable_init (GInitable *initable,
 		source->priv->uid = e_uid_new ();
 	}
 
+	/* Try to avoid a spurious "changed" emission. */
+	g_mutex_lock (source->priv->changed_lock);
+	if (source->priv->changed != NULL) {
+		g_source_destroy (source->priv->changed);
+		g_source_unref (source->priv->changed);
+		source->priv->changed = NULL;
+	}
+	g_mutex_unlock (source->priv->changed_lock);
+
+	source->priv->initialized = TRUE;
+
 	return success;
 }
 



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