Blame SOURCES/evolution-data-server-3.12.11-imapx-empty-cache-file-temp-workaround.patch

5e6360
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.c.imapx-empty-cache-file-temp-workaround evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.c
5e6360
--- evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.c.imapx-empty-cache-file-temp-workaround	2014-06-16 15:00:03.000000000 +0200
5e6360
+++ evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.c	2015-05-26 15:02:30.395243456 +0200
5e6360
@@ -182,6 +182,7 @@ camel_imapx_job_wait (CamelIMAPXJob *job
5e6360
 {
5e6360
 	CamelIMAPXRealJob *real_job;
5e6360
 	GCancellable *cancellable;
5e6360
+	gulong cancel_id = 0;
5e6360
 	gboolean success = TRUE;
5e6360
 
5e6360
 	g_return_val_if_fail (CAMEL_IS_IMAPX_JOB (job), FALSE);
5e6360
@@ -189,13 +190,23 @@ camel_imapx_job_wait (CamelIMAPXJob *job
5e6360
 	real_job = (CamelIMAPXRealJob *) job;
5e6360
 	cancellable = camel_imapx_job_get_cancellable (job);
5e6360
 
5e6360
+	if (G_IS_CANCELLABLE (cancellable))
5e6360
+		cancel_id = g_cancellable_connect (
5e6360
+			cancellable,
5e6360
+			G_CALLBACK (imapx_job_cancelled_cb),
5e6360
+			camel_imapx_job_ref (job),
5e6360
+			(GDestroyNotify) camel_imapx_job_unref);
5e6360
+
5e6360
 	g_mutex_lock (&real_job->done_mutex);
5e6360
-	while (!real_job->done_flag)
5e6360
+	while (!real_job->done_flag && !g_cancellable_is_cancelled (cancellable))
5e6360
 		g_cond_wait (
5e6360
 			&real_job->done_cond,
5e6360
 			&real_job->done_mutex);
5e6360
 	g_mutex_unlock (&real_job->done_mutex);
5e6360
 
5e6360
+	if (cancel_id > 0)
5e6360
+		g_cancellable_disconnect (cancellable, cancel_id);
5e6360
+
5e6360
 	/* Cancellation takes priority over other errors. */
5e6360
 	if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
5e6360
 		success = FALSE;
5e6360
@@ -233,7 +244,6 @@ camel_imapx_job_run (CamelIMAPXJob *job,
5e6360
                      GError **error)
5e6360
 {
5e6360
 	GCancellable *cancellable;
5e6360
-	gulong cancel_id = 0;
5e6360
 	gboolean success;
5e6360
 
5e6360
 	g_return_val_if_fail (CAMEL_IS_IMAPX_JOB (job), FALSE);
5e6360
@@ -245,21 +255,11 @@ camel_imapx_job_run (CamelIMAPXJob *job,
5e6360
 	if (g_cancellable_set_error_if_cancelled (cancellable, error))
5e6360
 		return FALSE;
5e6360
 
5e6360
-	if (G_IS_CANCELLABLE (cancellable))
5e6360
-		cancel_id = g_cancellable_connect (
5e6360
-			cancellable,
5e6360
-			G_CALLBACK (imapx_job_cancelled_cb),
5e6360
-			camel_imapx_job_ref (job),
5e6360
-			(GDestroyNotify) camel_imapx_job_unref);
5e6360
-
5e6360
 	success = job->start (job, is, cancellable, error);
5e6360
 
5e6360
 	if (success && !job->noreply)
5e6360
 		success = camel_imapx_job_wait (job, error);
5e6360
 
5e6360
-	if (cancel_id > 0)
5e6360
-		g_cancellable_disconnect (cancellable, cancel_id);
5e6360
-
5e6360
 	return success;
5e6360
 }
5e6360
 
5e6360
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.c.imapx-empty-cache-file-temp-workaround evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.c
5e6360
--- evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.c.imapx-empty-cache-file-temp-workaround	2015-05-26 15:02:30.390243457 +0200
5e6360
+++ evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.c	2015-05-26 15:02:46.146242702 +0200
5e6360
@@ -57,8 +57,8 @@
5e6360
 #define c(...) camel_imapx_debug(command, __VA_ARGS__)
5e6360
 #define e(...) camel_imapx_debug(extra, __VA_ARGS__)
5e6360
 
5e6360
-#define QUEUE_LOCK(x) (g_rec_mutex_lock(&(x)->queue_lock))
5e6360
-#define QUEUE_UNLOCK(x) (g_rec_mutex_unlock(&(x)->queue_lock))
5e6360
+#define QUEUE_LOCK(x) g_rec_mutex_lock (&(x)->queue_lock)
5e6360
+#define QUEUE_UNLOCK(x) g_rec_mutex_unlock (&(x)->queue_lock)
5e6360
 
5e6360
 /* Try pipelining fetch requests, 'in bits' */
5e6360
 #define MULTI_SIZE (32768 * 8)
5e6360
@@ -5172,23 +5172,54 @@ imapx_command_fetch_message_done (CamelI
5e6360
 		g_free (tmp_filename);
5e6360
 	}
5e6360
 
5e6360
-	/* Delete the 'tmp' file only if the operation wasn't cancelled. It's because
5e6360
+	/* Delete the 'tmp' file only if the operation succeeded. It's because
5e6360
 	   cancelled operations end before they are properly finished (IMAP-protocol speaking),
5e6360
 	   thus if any other GET_MESSAGE operation was waiting for this job, then it
5e6360
 	   realized that the message was not downloaded and opened its own "tmp" file, but
5e6360
 	   of the same name, thus this remove would drop file which could be used
5e6360
 	   by a different GET_MESSAGE job. */
5e6360
-	if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
5e6360
+	if (!local_error && !g_cancellable_is_cancelled (cancellable))
5e6360
 		camel_data_cache_remove (data->message_cache, "tmp", data->uid, NULL);
5e6360
 
5e6360
 	/* Avoid possible use-after-free when the imapx_unregister_job() can
5e6360
 	   also free the 'job' structure. */
5e6360
+	camel_imapx_job_ref (job);
5e6360
+
5e6360
+	imapx_unregister_job (is, job);
5e6360
+
5e6360
 	if (local_error != NULL) {
5e6360
-		camel_imapx_job_take_error (job, local_error);
5e6360
-		local_error = NULL;
5e6360
+		CamelIMAPXJob *pending_job;
5e6360
+
5e6360
+		/* Give a chance to other threads. */
5e6360
+		g_thread_yield ();
5e6360
+
5e6360
+		pending_job = imapx_server_ref_job (is, mailbox, IMAPX_JOB_GET_MESSAGE, data->uid);
5e6360
+		if (pending_job != NULL) {
5e6360
+			GIOStream *cache_stream;
5e6360
+
5e6360
+			/* Wait for the job to finish. */
5e6360
+			camel_imapx_job_wait (pending_job, NULL);
5e6360
+			camel_imapx_job_unref (pending_job);
5e6360
+
5e6360
+			/* Disregard errors here.  If we failed to retrieve the
5e6360
+			 * message from cache (implying the job we were waiting
5e6360
+			 * on failed or got cancelled), we'll just re-fetch it. */
5e6360
+			cache_stream = camel_data_cache_get (data->message_cache, "cur", data->uid, NULL);
5e6360
+			if (cache_stream != NULL) {
5e6360
+				g_clear_error (&local_error);
5e6360
+
5e6360
+				g_clear_object (&data->stream);
5e6360
+				data->stream = cache_stream;
5e6360
+			}
5e6360
+		}
5e6360
+
5e6360
+		if (local_error) {
5e6360
+			camel_imapx_job_take_error (job, local_error);
5e6360
+			local_error = NULL;
5e6360
+		}
5e6360
 	}
5e6360
 
5e6360
-	imapx_unregister_job (is, job);
5e6360
+	camel_imapx_job_unref (job);
5e6360
 
5e6360
 exit:
5e6360
 	if (local_error != NULL)
5e6360
@@ -8344,9 +8375,7 @@ imapx_server_get_message (CamelIMAPXServ
5e6360
 	GetMessageData *data;
5e6360
 	gboolean registered;
5e6360
 
5e6360
-	job = imapx_server_ref_job (is, mailbox, IMAPX_JOB_GET_MESSAGE, message_uid);
5e6360
-
5e6360
-	if (job != NULL) {
5e6360
+	while (job = imapx_server_ref_job (is, mailbox, IMAPX_JOB_GET_MESSAGE, message_uid), job != NULL) {
5e6360
 		/* Promote the existing GET_MESSAGE
5e6360
 		 * job's priority if ours is higher. */
5e6360
 		if (pri > job->pri)
5e6360
@@ -8362,14 +8391,26 @@ imapx_server_get_message (CamelIMAPXServ
5e6360
 		cache_stream = camel_data_cache_get (
5e6360
 			message_cache, "cur", message_uid, NULL);
5e6360
 		if (cache_stream != NULL) {
5e6360
-			stream = camel_stream_new (cache_stream);
5e6360
+			/* Return new file stream, instead of a DataCache's to not fight
5e6360
+			   on its content and position with other jobs, if any. */
5e6360
+			gchar *filename = camel_data_cache_get_filename (message_cache, "cur", message_uid);
5e6360
+			stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0, NULL);
5e6360
+			g_free (filename);
5e6360
 			g_object_unref (cache_stream);
5e6360
-			return stream;
5e6360
+
5e6360
+			if (stream)
5e6360
+				return stream;
5e6360
 		}
5e6360
 	}
5e6360
 
5e6360
 	QUEUE_LOCK (is);
5e6360
 
5e6360
+	if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
5e6360
+		QUEUE_UNLOCK (is);
5e6360
+
5e6360
+		return NULL;
5e6360
+	}
5e6360
+
5e6360
 	mi = camel_folder_summary_get (summary, message_uid);
5e6360
 	if (mi == NULL) {
5e6360
 		g_set_error (
5e6360
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.h.imapx-empty-cache-file-temp-workaround evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.h
5e6360
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-store.c.imapx-empty-cache-file-temp-workaround evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-store.c
5e6360
--- evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-store.c.imapx-empty-cache-file-temp-workaround	2014-12-02 16:07:54.000000000 +0100
5e6360
+++ evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-store.c	2015-05-26 15:02:46.148242702 +0200
5e6360
@@ -704,7 +704,6 @@ imapx_store_finalize (GObject *object)
5e6360
 	priv = CAMEL_IMAPX_STORE_GET_PRIVATE (object);
5e6360
 
5e6360
 	g_mutex_clear (&priv->get_finfo_lock);
5e6360
-
5e6360
 	g_mutex_clear (&priv->server_lock);
5e6360
 
5e6360
 	g_hash_table_destroy (priv->quota_info);
5e6360
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-store.h.imapx-empty-cache-file-temp-workaround evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-store.h