Blame SOURCES/evolution-data-server-3.22.7-deadlock-categories-finalize.patch

1e20f1
diff -up evolution-data-server-3.22.7/libedataserver/e-categories.c.deadlock-categories-finalize evolution-data-server-3.22.7/libedataserver/e-categories.c
1e20f1
--- evolution-data-server-3.22.7/libedataserver/e-categories.c.deadlock-categories-finalize	2017-03-20 10:07:46.000000000 +0100
1e20f1
+++ evolution-data-server-3.22.7/libedataserver/e-categories.c	2017-10-19 17:44:13.306338284 +0200
1e20f1
@@ -224,8 +224,9 @@ hash_to_xml_string (gpointer key,
1e20f1
 	g_string_append_len (string, "/>\n", 3);
1e20f1
 }
1e20f1
 
1e20f1
-static gboolean
1e20f1
-idle_saver_cb (gpointer user_data)
1e20f1
+/* Called with the @categories lock locked */
1e20f1
+static void
1e20f1
+idle_saver_save (void)
1e20f1
 {
1e20f1
 	GString *buffer;
1e20f1
 	gchar *contents;
1e20f1
@@ -234,8 +235,6 @@ idle_saver_cb (gpointer user_data)
1e20f1
 	EChangedListener *emit_listeners = NULL;  /* owned */
1e20f1
 	GError *error = NULL;
1e20f1
 
1e20f1
-	G_LOCK (categories);
1e20f1
-
1e20f1
 	if (!save_is_pending)
1e20f1
 		goto exit;
1e20f1
 
1e20f1
@@ -269,14 +268,26 @@ idle_saver_cb (gpointer user_data)
1e20f1
 exit:
1e20f1
 	idle_id = 0;
1e20f1
 
1e20f1
-	G_UNLOCK (categories);
1e20f1
-
1e20f1
 	/* Emit the signal with the lock released to avoid re-entrancy
1e20f1
 	 * deadlocks. Hold a reference to @listeners until this is complete. */
1e20f1
 	if (emit_listeners) {
1e20f1
+		G_UNLOCK (categories);
1e20f1
+
1e20f1
 		g_signal_emit_by_name (emit_listeners, "changed");
1e20f1
 		g_object_unref (emit_listeners);
1e20f1
+
1e20f1
+		G_LOCK (categories);
1e20f1
 	}
1e20f1
+}
1e20f1
+
1e20f1
+static gboolean
1e20f1
+idle_saver_cb (gpointer user_data)
1e20f1
+{
1e20f1
+	G_LOCK (categories);
1e20f1
+
1e20f1
+	idle_saver_save ();
1e20f1
+
1e20f1
+	G_UNLOCK (categories);
1e20f1
 
1e20f1
 	return FALSE;
1e20f1
 }
1e20f1
@@ -462,7 +473,7 @@ finalize_categories (void)
1e20f1
 	G_LOCK (categories);
1e20f1
 
1e20f1
 	if (save_is_pending)
1e20f1
-		idle_saver_cb (NULL);
1e20f1
+		idle_saver_save ();
1e20f1
 
1e20f1
 	if (idle_id > 0) {
1e20f1
 		g_source_remove (idle_id);