Blame SOURCES/evolution-data-server-3.8.5-imapx-error-cancelled-message-download.patch

59ad60
diff -up evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.c.imapx-error-cancelled-message-download evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.c
59ad60
--- evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.c.imapx-error-cancelled-message-download	2014-05-16 11:36:17.872612953 +0200
59ad60
+++ evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.c	2014-05-16 11:36:17.884612846 +0200
59ad60
@@ -883,3 +883,21 @@ camel_imapx_conn_manager_close_connectio
59ad60
 	g_list_free_full (connections, (GDestroyNotify) connection_info_cancel_and_unref);
59ad60
 }
59ad60
 
59ad60
+/* for debugging purposes only */
59ad60
+void
59ad60
+camel_imapx_conn_manager_dump_queue_status (CamelIMAPXConnManager *con_man)
59ad60
+{
59ad60
+	GList *list, *link;
59ad60
+
59ad60
+	g_return_if_fail (CAMEL_IS_IMAPX_CONN_MANAGER (con_man));
59ad60
+
59ad60
+	list = imapx_conn_manager_list_info (con_man);
59ad60
+
59ad60
+	for (link = list; link != NULL; link = g_list_next (link)) {
59ad60
+		ConnectionInfo *cinfo = link->data;
59ad60
+		camel_imapx_server_dump_queue_status (cinfo->is);
59ad60
+		connection_info_unref (cinfo);
59ad60
+	}
59ad60
+
59ad60
+	g_list_free (list);
59ad60
+}
59ad60
diff -up evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.h.imapx-error-cancelled-message-download evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.h
59ad60
--- evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.h.imapx-error-cancelled-message-download	2014-05-16 11:36:17.873612944 +0200
59ad60
+++ evolution-data-server-3.8.5/camel/camel-imapx-conn-manager.h	2014-05-16 11:36:17.884612846 +0200
59ad60
@@ -84,6 +84,10 @@ void		camel_imapx_conn_manager_update_co
59ad60
 						 CamelIMAPXServer *server,
59ad60
 						 const gchar *folder_name);
59ad60
 
59ad60
+/* for debugging purposes only */
59ad60
+void		camel_imapx_conn_manager_dump_queue_status
59ad60
+						(CamelIMAPXConnManager *con_man);
59ad60
+
59ad60
 G_END_DECLS
59ad60
 
59ad60
 #endif /* _CAMEL_IMAPX_SERVER_H */
59ad60
diff -up evolution-data-server-3.8.5/camel/camel-imapx-job.h.imapx-error-cancelled-message-download evolution-data-server-3.8.5/camel/camel-imapx-job.h
59ad60
--- evolution-data-server-3.8.5/camel/camel-imapx-job.h.imapx-error-cancelled-message-download	2014-05-16 11:36:17.798613612 +0200
59ad60
+++ evolution-data-server-3.8.5/camel/camel-imapx-job.h	2014-05-16 11:36:17.884612846 +0200
59ad60
@@ -55,7 +55,7 @@ struct _CamelIMAPXJob {
59ad60
 	guint noreply:1;	/* dont wait for reply */
59ad60
 	guint32 type;		/* operation type */
59ad60
 	gint pri;		/* the command priority */
59ad60
-	gshort commands;	/* counts how many commands are outstanding */
59ad60
+	volatile gint commands;	/* counts how many commands are outstanding */
59ad60
 };
59ad60
 
59ad60
 CamelIMAPXJob *	camel_imapx_job_new		(GCancellable *cancellable);
59ad60
diff -up evolution-data-server-3.8.5/camel/camel-imapx-server.c.imapx-error-cancelled-message-download evolution-data-server-3.8.5/camel/camel-imapx-server.c
59ad60
--- evolution-data-server-3.8.5/camel/camel-imapx-server.c.imapx-error-cancelled-message-download	2014-05-16 11:36:17.879612890 +0200
59ad60
+++ evolution-data-server-3.8.5/camel/camel-imapx-server.c	2014-05-16 11:36:17.885612837 +0200
59ad60
@@ -989,9 +989,7 @@ imapx_uidset_add (struct _uidset_state *
59ad60
 /* Must hold QUEUE_LOCK */
59ad60
 static gboolean
59ad60
 imapx_command_start (CamelIMAPXServer *is,
59ad60
-                     CamelIMAPXCommand *ic,
59ad60
-                     GCancellable *cancellable,
59ad60
-                     GError **error)
59ad60
+                     CamelIMAPXCommand *ic)
59ad60
 {
59ad60
 	CamelIMAPXStream *stream = NULL;
59ad60
 	CamelIMAPXCommandPart *cp;
59ad60
@@ -1002,6 +1000,7 @@ imapx_command_start (CamelIMAPXServer *i
59ad60
 	gboolean success = FALSE;
59ad60
 	gchar *string;
59ad60
 	gint retval;
59ad60
+	GCancellable *cancellable;
59ad60
 	GError *local_error = NULL;
59ad60
 
59ad60
 	camel_imapx_command_close (ic);
59ad60
@@ -1024,7 +1023,11 @@ imapx_command_start (CamelIMAPXServer *i
59ad60
 	imapx_server_command_added (is, ic);
59ad60
 
59ad60
 	job = camel_imapx_command_get_job (ic);
59ad60
-	if (job && g_cancellable_set_error_if_cancelled (camel_imapx_job_get_cancellable (job), &local_error)) {
59ad60
+	if (job)
59ad60
+		cancellable = camel_imapx_job_get_cancellable (job);
59ad60
+	else
59ad60
+		cancellable = NULL;
59ad60
+	if (job && g_cancellable_set_error_if_cancelled (cancellable, &local_error)) {
59ad60
 		camel_imapx_job_set_error (job, local_error);
59ad60
 		g_clear_error (&local_error);
59ad60
 		goto err;
59ad60
@@ -1034,7 +1037,7 @@ imapx_command_start (CamelIMAPXServer *i
59ad60
 
59ad60
 	if (stream == NULL) {
59ad60
 		g_set_error (
59ad60
-			error, CAMEL_IMAPX_ERROR, 1,
59ad60
+			&local_error, CAMEL_IMAPX_ERROR, 1,
59ad60
 			"Cannot issue command, no stream available");
59ad60
 		goto err;
59ad60
 	}
59ad60
@@ -1052,7 +1055,7 @@ imapx_command_start (CamelIMAPXServer *i
59ad60
 	string = g_strdup_printf (
59ad60
 		"%c%05u %s\r\n", is->tagprefix, ic->tag, cp->data);
59ad60
 	retval = camel_stream_write_string (
59ad60
-		CAMEL_STREAM (stream), string, cancellable, error);
59ad60
+		CAMEL_STREAM (stream), string, cancellable, &local_error);
59ad60
 	g_free (string);
59ad60
 
59ad60
 	if (retval == -1)
59ad60
@@ -1060,7 +1063,7 @@ imapx_command_start (CamelIMAPXServer *i
59ad60
 
59ad60
 	while (is->literal == ic && cp_literal_plus) {
59ad60
 		/* Sent LITERAL+ continuation immediately */
59ad60
-		if (!imapx_continuation (is, stream, TRUE, cancellable, error))
59ad60
+		if (!imapx_continuation (is, stream, TRUE, cancellable, &local_error))
59ad60
 			goto err;
59ad60
 	}
59ad60
 
59ad60
@@ -1080,6 +1083,10 @@ err:
59ad60
 	if (ic->status->result == IMAPX_OK)
59ad60
 		ic->status->result = IMAPX_UNKNOWN;
59ad60
 
59ad60
+	if (job && local_error) {
59ad60
+		camel_imapx_job_set_error (job, local_error);
59ad60
+		g_clear_error (&local_error);
59ad60
+	}
59ad60
 	/* Send a NULL GError since we've already set a
59ad60
 	 * GError to get here, and we're not interested
59ad60
 	 * in individual command errors. */
59ad60
@@ -1134,9 +1141,7 @@ duplicate_fetch_or_refresh (CamelIMAPXSe
59ad60
  * must have QUEUE lock */
59ad60
 
59ad60
 static gboolean
59ad60
-imapx_command_start_next (CamelIMAPXServer *is,
59ad60
-                          GCancellable *cancellable,
59ad60
-                          GError **error)
59ad60
+imapx_command_start_next (CamelIMAPXServer *is)
59ad60
 {
59ad60
 	CamelIMAPXCommand *first_ic;
59ad60
 	CamelFolder *folder;
59ad60
@@ -1151,7 +1156,7 @@ imapx_command_start_next (CamelIMAPXServ
59ad60
 
59ad60
 	folder = g_weak_ref_get (&is->select_pending);
59ad60
 	if (folder != NULL) {
59ad60
-		GQueue start = G_QUEUE_INIT;
59ad60
+		CamelIMAPXCommand *start_ic = NULL;
59ad60
 		GList *head, *link;
59ad60
 
59ad60
 		c (is->tagprefix, "-- Checking job queue for non-folder jobs\n");
59ad60
@@ -1159,7 +1164,7 @@ imapx_command_start_next (CamelIMAPXServ
59ad60
 		head = camel_imapx_command_queue_peek_head_link (is->queue);
59ad60
 
59ad60
 		/* Tag which commands in the queue to start. */
59ad60
-		for (link = head; link != NULL; link = g_list_next (link)) {
59ad60
+		for (link = head; link != NULL && !start_ic; link = g_list_next (link)) {
59ad60
 			CamelIMAPXCommand *ic = link->data;
59ad60
 
59ad60
 			if (ic->pri < min_pri)
59ad60
@@ -1169,37 +1174,23 @@ imapx_command_start_next (CamelIMAPXServ
59ad60
 			if (!ic->select) {
59ad60
 				c (is->tagprefix, "--> starting '%s'\n", ic->name);
59ad60
 				min_pri = ic->pri;
59ad60
-				g_queue_push_tail (&start, link);
59ad60
-			}
59ad60
 
59ad60
-			if (g_queue_get_length (&start) == MAX_COMMANDS)
59ad60
-				break;
59ad60
+				/* Each command must be removed from 'is->queue' before
59ad60
+				 * starting it, so we temporarily reference the command
59ad60
+				 * to avoid accidentally finalizing it. */
59ad60
+				start_ic = camel_imapx_command_ref (ic);
59ad60
+			}
59ad60
 		}
59ad60
 
59ad60
-		if (g_queue_is_empty (&start))
59ad60
+		if (!start_ic)
59ad60
 			c (is->tagprefix, "* no, waiting for pending select '%s'\n", camel_folder_get_full_name (folder));
59ad60
 
59ad60
-		/* Start the tagged commands.
59ad60
-		 *
59ad60
-		 * Each command must be removed from 'is->queue' before
59ad60
-		 * starting it, so we temporarily reference the command
59ad60
-		 * to avoid accidentally finalizing it. */
59ad60
-		while ((link = g_queue_pop_head (&start)) != NULL) {
59ad60
-			CamelIMAPXCommand *ic;
59ad60
-
59ad60
-			ic = camel_imapx_command_ref (link->data);
59ad60
-			camel_imapx_command_queue_delete_link (is->queue, link);
59ad60
-			imapx_server_command_removed (is, ic);
59ad60
-
59ad60
-			success = imapx_command_start (
59ad60
-				is, ic, cancellable, error);
59ad60
-
59ad60
-			camel_imapx_command_unref (ic);
59ad60
-
59ad60
-			if (!success) {
59ad60
-				g_queue_clear (&start;;
59ad60
-				break;
59ad60
-			}
59ad60
+		/* Start the tagged command */
59ad60
+		if (start_ic) {
59ad60
+			camel_imapx_command_queue_remove (is->queue, start_ic);
59ad60
+			imapx_server_command_removed (is, start_ic);
59ad60
+			imapx_command_start (is, start_ic);
59ad60
+			camel_imapx_command_unref (start_ic);
59ad60
 		}
59ad60
 
59ad60
 		g_clear_object (&folder);
59ad60
@@ -1219,7 +1210,7 @@ imapx_command_start_next (CamelIMAPXServ
59ad60
 
59ad60
 			if (stream != NULL) {
59ad60
 				stop_result = imapx_stop_idle (
59ad60
-					is, stream, cancellable, error);
59ad60
+					is, stream, is->cancellable, NULL);
59ad60
 				g_object_unref (stream);
59ad60
 			}
59ad60
 
59ad60
@@ -1255,9 +1246,8 @@ imapx_command_start_next (CamelIMAPXServ
59ad60
 	/* See if any queued jobs on this select first */
59ad60
 	folder = g_weak_ref_get (&is->select_folder);
59ad60
 	if (folder != NULL) {
59ad60
-		GQueue start = G_QUEUE_INIT;
59ad60
+		CamelIMAPXCommand *start_ic = NULL;
59ad60
 		GList *head, *link;
59ad60
-		gboolean commands_started = FALSE;
59ad60
 
59ad60
 		c (
59ad60
 			is->tagprefix, "- we're selected on '%s', current jobs?\n",
59ad60
@@ -1284,7 +1274,7 @@ imapx_command_start_next (CamelIMAPXServ
59ad60
 		head = camel_imapx_command_queue_peek_head_link (is->queue);
59ad60
 
59ad60
 		/* Tag which commands in the queue to start. */
59ad60
-		for (link = head; link != NULL; link = g_list_next (link)) {
59ad60
+		for (link = head; link != NULL && !start_ic; link = g_list_next (link)) {
59ad60
 			CamelIMAPXCommand *ic = link->data;
59ad60
 
59ad60
 			if (is->literal != NULL)
59ad60
@@ -1299,48 +1289,29 @@ imapx_command_start_next (CamelIMAPXServ
59ad60
 					    !duplicate_fetch_or_refresh (is, ic))) {
59ad60
 				c (is->tagprefix, "--> starting '%s'\n", ic->name);
59ad60
 				min_pri = ic->pri;
59ad60
-				g_queue_push_tail (&start, link);
59ad60
+				/* Each command must be removed from 'is->queue' before
59ad60
+				 * starting it, so we temporarily reference the command
59ad60
+				 * to avoid accidentally finalizing it. */
59ad60
+				start_ic = camel_imapx_command_ref (ic);
59ad60
 			} else {
59ad60
 				/* This job isn't for the selected folder, but we don't want to
59ad60
 				 * consider jobs with _lower_ priority than this, even if they
59ad60
 				 * are for the selected folder. */
59ad60
 				min_pri = ic->pri;
59ad60
 			}
59ad60
-
59ad60
-			if (g_queue_get_length (&start) == MAX_COMMANDS)
59ad60
-				break;
59ad60
 		}
59ad60
 
59ad60
 		g_clear_object (&folder);
59ad60
 
59ad60
-		/* Start the tagged commands.
59ad60
-		 *
59ad60
-		 * Each command must be removed from 'is->queue' before
59ad60
-		 * starting it, so we temporarily reference the command
59ad60
-		 * to avoid accidentally finalizing it. */
59ad60
-		while ((link = g_queue_pop_head (&start)) != NULL) {
59ad60
-			CamelIMAPXCommand *ic;
59ad60
-			gboolean success;
59ad60
+		/* Start the tagged command */
59ad60
+		if (start_ic) {
59ad60
+			camel_imapx_command_queue_remove (is->queue, start_ic);
59ad60
+			imapx_server_command_removed (is, start_ic);
59ad60
+			imapx_command_start (is, start_ic);
59ad60
+			camel_imapx_command_unref (start_ic);
59ad60
 
59ad60
-			ic = camel_imapx_command_ref (link->data);
59ad60
-			camel_imapx_command_queue_delete_link (is->queue, link);
59ad60
-			imapx_server_command_removed (is, ic);
59ad60
-
59ad60
-			success = imapx_command_start (
59ad60
-				is, ic, cancellable, error);
59ad60
-
59ad60
-			camel_imapx_command_unref (ic);
59ad60
-
59ad60
-			if (!success) {
59ad60
-				g_queue_clear (&start;;
59ad60
-				return FALSE;
59ad60
-			}
59ad60
-
59ad60
-			commands_started = TRUE;
59ad60
-		}
59ad60
-
59ad60
-		if (commands_started)
59ad60
 			return TRUE;
59ad60
+		}
59ad60
 	}
59ad60
 
59ad60
 	/* This won't be NULL because we checked for an empty queue above. */
59ad60
@@ -1349,13 +1320,19 @@ imapx_command_start_next (CamelIMAPXServ
59ad60
 	/* If we need to select a folder for the first command, do it now,
59ad60
 	 * once it is complete it will re-call us if it succeeded. */
59ad60
 	if (first_ic->select) {
59ad60
+		GError *local_error = NULL;
59ad60
+		CamelIMAPXJob *job;
59ad60
 		c (
59ad60
 			is->tagprefix, "Selecting folder '%s' for command '%s'(%p)\n",
59ad60
 			camel_folder_get_full_name (first_ic->select),
59ad60
 			first_ic->name, first_ic);
59ad60
-		imapx_select (is, first_ic->select, FALSE, cancellable, error);
59ad60
+		job = camel_imapx_command_get_job (first_ic);
59ad60
+		imapx_select (is, first_ic->select, FALSE, job ? camel_imapx_job_get_cancellable (job) : NULL, &local_error);
59ad60
+		if (local_error && job)
59ad60
+			camel_imapx_job_set_error (job, local_error);
59ad60
+		g_clear_error (&local_error);
59ad60
 	} else {
59ad60
-		GQueue start = G_QUEUE_INIT;
59ad60
+		CamelIMAPXCommand *start_ic = NULL;
59ad60
 		GList *head, *link;
59ad60
 
59ad60
 		min_pri = first_ic->pri;
59ad60
@@ -1365,7 +1342,7 @@ imapx_command_start_next (CamelIMAPXServ
59ad60
 		head = camel_imapx_command_queue_peek_head_link (is->queue);
59ad60
 
59ad60
 		/* Tag which commands in the queue to start. */
59ad60
-		for (link = head; link != NULL; link = g_list_next (link)) {
59ad60
+		for (link = head; link != NULL && !start_ic; link = g_list_next (link)) {
59ad60
 			CamelIMAPXCommand *ic = link->data;
59ad60
 
59ad60
 			if (is->literal != NULL)
59ad60
@@ -1378,37 +1355,21 @@ imapx_command_start_next (CamelIMAPXServ
59ad60
 					    !duplicate_fetch_or_refresh (is, ic))) {
59ad60
 				c (is->tagprefix, "* queueing job %3d '%s'\n", (gint) ic->pri, ic->name);
59ad60
 				min_pri = ic->pri;
59ad60
-				g_queue_push_tail (&start, link);
59ad60
+				/* Each command must be removed from 'is->queue' before
59ad60
+				 * starting it, so we temporarily reference the command
59ad60
+				 * to avoid accidentally finalizing it. */
59ad60
+				start_ic = camel_imapx_command_ref (ic);
59ad60
 			}
59ad60
-
59ad60
-			if (g_queue_get_length (&start) == MAX_COMMANDS)
59ad60
-				break;
59ad60
 		}
59ad60
 
59ad60
 		g_clear_object (&folder);
59ad60
 
59ad60
-		/* Start the tagged commands.
59ad60
-		 *
59ad60
-		 * Each command must be removed from 'is->queue' before
59ad60
-		 * starting it, so we temporarily reference the command
59ad60
-		 * to avoid accidentally finalizing it. */
59ad60
-		while ((link = g_queue_pop_head (&start)) != NULL) {
59ad60
-			CamelIMAPXCommand *ic;
59ad60
-			gboolean success;
59ad60
-
59ad60
-			ic = camel_imapx_command_ref (link->data);
59ad60
-			camel_imapx_command_queue_delete_link (is->queue, link);
59ad60
-			imapx_server_command_removed (is, ic);
59ad60
-
59ad60
-			success = imapx_command_start (
59ad60
-				is, ic, cancellable, error);
59ad60
-
59ad60
-			camel_imapx_command_unref (ic);
59ad60
-
59ad60
-			if (!success) {
59ad60
-				g_queue_clear (&start;;
59ad60
-				return FALSE;
59ad60
-			}
59ad60
+		/* Start the tagged command */
59ad60
+		if (start_ic) {
59ad60
+			camel_imapx_command_queue_remove (is->queue, start_ic);
59ad60
+			imapx_server_command_removed (is, start_ic);
59ad60
+			imapx_command_start (is, start_ic);
59ad60
+			camel_imapx_command_unref (start_ic);
59ad60
 		}
59ad60
 	}
59ad60
 
59ad60
@@ -1430,7 +1391,6 @@ imapx_is_command_queue_empty (CamelIMAPX
59ad60
 static gboolean
59ad60
 imapx_command_queue (CamelIMAPXServer *is,
59ad60
                      CamelIMAPXCommand *ic,
59ad60
-                     GCancellable *cancellable,
59ad60
                      GError **error)
59ad60
 {
59ad60
 	CamelIMAPXJob *job;
59ad60
@@ -1472,7 +1432,7 @@ imapx_command_queue (CamelIMAPXServer *i
59ad60
 	camel_imapx_command_queue_insert_sorted (is->queue, ic);
59ad60
 	imapx_server_command_added (is, ic);
59ad60
 
59ad60
-	success = imapx_command_start_next (is, cancellable, error);
59ad60
+	success = imapx_command_start_next (is);
59ad60
 
59ad60
 	QUEUE_UNLOCK (is);
59ad60
 
59ad60
@@ -2808,7 +2768,7 @@ imapx_continuation (CamelIMAPXServer *is
59ad60
 
59ad60
 		QUEUE_LOCK (is);
59ad60
 		is->literal = NULL;
59ad60
-		success = imapx_command_start_next (is, cancellable, error);
59ad60
+		success = imapx_command_start_next (is);
59ad60
 		QUEUE_UNLOCK (is);
59ad60
 
59ad60
 		return success;
59ad60
@@ -2950,7 +2910,7 @@ noskip:
59ad60
 	is->literal = newliteral;
59ad60
 
59ad60
 	if (!litplus)
59ad60
-		success = imapx_command_start_next (is, cancellable, error);
59ad60
+		success = imapx_command_start_next (is);
59ad60
 	QUEUE_UNLOCK (is);
59ad60
 
59ad60
 	return success;
59ad60
@@ -3063,7 +3023,7 @@ imapx_completion (CamelIMAPXServer *is,
59ad60
 	camel_imapx_command_unref (ic);
59ad60
 
59ad60
 	QUEUE_LOCK (is);
59ad60
-	success = imapx_command_start_next (is, cancellable, error);
59ad60
+	success = imapx_command_start_next (is);
59ad60
 	QUEUE_UNLOCK (is);
59ad60
 
59ad60
 	return success;
59ad60
@@ -3129,7 +3089,7 @@ imapx_command_run (CamelIMAPXServer *is,
59ad60
 	camel_imapx_command_close (ic);
59ad60
 
59ad60
 	QUEUE_LOCK (is);
59ad60
-	imapx_command_start (is, ic, cancellable, error);
59ad60
+	imapx_command_start (is, ic);
59ad60
 	QUEUE_UNLOCK (is);
59ad60
 
59ad60
 	while (success && ic->status == NULL)
59ad60
@@ -3200,7 +3160,7 @@ imapx_command_run_sync (CamelIMAPXServer
59ad60
 	/* Unref'ed in imapx_command_complete(). */
59ad60
 	camel_imapx_command_ref (ic);
59ad60
 
59ad60
-	success = imapx_command_queue (is, ic, cancellable, error);
59ad60
+	success = imapx_command_queue (is, ic, error);
59ad60
 
59ad60
 	if (success)
59ad60
 		camel_imapx_command_wait (ic);
59ad60
@@ -3252,10 +3212,14 @@ imapx_unregister_job (CamelIMAPXServer *
59ad60
 		camel_imapx_job_done (job);
59ad60
 
59ad60
 	QUEUE_LOCK (is);
59ad60
+
59ad60
 	if (g_queue_remove (&is->jobs, job)) {
59ad60
 		imapx_server_job_removed (is, job);
59ad60
 		camel_imapx_job_unref (job);
59ad60
 	}
59ad60
+
59ad60
+	imapx_command_start_next (is);
59ad60
+
59ad60
 	QUEUE_UNLOCK (is);
59ad60
 }
59ad60
 
59ad60
@@ -3361,7 +3325,7 @@ imapx_job_idle_start (CamelIMAPXJob *job
59ad60
 	/* Don't issue it if the idle was cancelled already */
59ad60
 	if (is->idle->state == IMAPX_IDLE_PENDING) {
59ad60
 		is->idle->state = IMAPX_IDLE_ISSUED;
59ad60
-		success = imapx_command_start (is, ic, cancellable, error);
59ad60
+		success = imapx_command_start (is, ic);
59ad60
 	} else {
59ad60
 		imapx_unregister_job (is, job);
59ad60
 		camel_imapx_command_unref (ic);
59ad60
@@ -3903,7 +3867,7 @@ imapx_select (CamelIMAPXServer *is,
59ad60
 		camel_imapx_command_add_qresync_parameter (ic, folder);
59ad60
 
59ad60
 	ic->complete = imapx_command_select_done;
59ad60
-	imapx_command_start (is, ic, cancellable, error);
59ad60
+	imapx_command_start (is, ic);
59ad60
 
59ad60
 	return TRUE;
59ad60
 }
59ad60
@@ -4579,6 +4543,7 @@ imapx_command_fetch_message_done (CamelI
59ad60
 	CamelFolder *folder;
59ad60
 	GetMessageData *data;
59ad60
 	CamelIMAPXFolder *ifolder;
59ad60
+	GError *local_error = NULL;
59ad60
 	gboolean success = TRUE;
59ad60
 
59ad60
 	job = camel_imapx_command_get_job (ic);
59ad60
@@ -4594,11 +4559,11 @@ imapx_command_fetch_message_done (CamelI
59ad60
 	 * or we failed.  Failure is handled in the fetch code, so
59ad60
 	 * we just return the job, or keep it alive with more requests */
59ad60
 
59ad60
-	job->commands--;
59ad60
+	g_atomic_int_add (&job->commands, -1);
59ad60
 
59ad60
-	if (camel_imapx_command_set_error_if_failed (ic, cancellable, error)) {
59ad60
+	if (camel_imapx_command_set_error_if_failed (ic, cancellable, &local_error)) {
59ad60
 		g_prefix_error (
59ad60
-			error, "%s: ",
59ad60
+			&local_error, "%s: ",
59ad60
 			_("Error fetching message"));
59ad60
 		data->body_len = -1;
59ad60
 		success = FALSE;
59ad60
@@ -4627,18 +4592,24 @@ imapx_command_fetch_message_done (CamelI
59ad60
 			camel_imapx_command_set_job (new_ic, job);
59ad60
 			new_ic->pri = job->pri - 1;
59ad60
 			data->fetch_offset += MULTI_SIZE;
59ad60
-			job->commands++;
59ad60
+			g_atomic_int_add (&job->commands, 1);
59ad60
 
59ad60
 			success = imapx_command_queue (
59ad60
-				is, new_ic, cancellable, error);
59ad60
+				is, new_ic, &local_error);
59ad60
 
59ad60
 			goto exit;
59ad60
 		}
59ad60
 	}
59ad60
 
59ad60
 	/* If we have more messages to fetch, skip the rest. */
59ad60
-	if (job->commands > 0)
59ad60
+	if (g_atomic_int_get (&job->commands) > 0) {
59ad60
+		/* Make sure no command will starve in a queue */
59ad60
+		QUEUE_LOCK (is);
59ad60
+		imapx_command_start_next (is);
59ad60
+		QUEUE_UNLOCK (is);
59ad60
+
59ad60
 		goto exit;
59ad60
+	}
59ad60
 
59ad60
 	/* No more messages to fetch, let's wrap things up. */
59ad60
 
59ad60
@@ -4646,24 +4617,24 @@ imapx_command_fetch_message_done (CamelI
59ad60
 
59ad60
 	if (success) {
59ad60
 		success = camel_stream_flush (
59ad60
-			data->stream, cancellable, error) == 0;
59ad60
+			data->stream, cancellable, &local_error) == 0;
59ad60
 		g_prefix_error (
59ad60
-			error, "%s: ",
59ad60
+			&local_error, "%s: ",
59ad60
 			_("Failed to close the tmp stream"));
59ad60
 	}
59ad60
 
59ad60
 	if (success) {
59ad60
 		success = camel_stream_close (
59ad60
-			data->stream, cancellable, error) == 0;
59ad60
+			data->stream, cancellable, &local_error) == 0;
59ad60
 		g_prefix_error (
59ad60
-			error, "%s: ",
59ad60
+			&local_error, "%s: ",
59ad60
 			_("Failed to close the tmp stream"));
59ad60
 	}
59ad60
 
59ad60
-	if (success && g_cancellable_set_error_if_cancelled (cancellable, error)) {
59ad60
+	if (success && g_cancellable_set_error_if_cancelled (cancellable, &local_error)) {
59ad60
 		success = FALSE;
59ad60
 		g_prefix_error (
59ad60
-			error, "%s: ",
59ad60
+			&local_error, "%s: ",
59ad60
 			_("Error fetching message"));
59ad60
 	}
59ad60
 
59ad60
@@ -4686,11 +4657,11 @@ imapx_command_fetch_message_done (CamelI
59ad60
 			/* Exchange the "tmp" stream for the "cur" stream. */
59ad60
 			g_clear_object (&data->stream);
59ad60
 			data->stream = camel_data_cache_get (
59ad60
-				ifolder->cache, "cur", data->uid, error);
59ad60
+				ifolder->cache, "cur", data->uid, &local_error);
59ad60
 			success = (data->stream != NULL);
59ad60
 		} else {
59ad60
 			g_set_error (
59ad60
-				error, G_FILE_ERROR,
59ad60
+				&local_error, G_FILE_ERROR,
59ad60
 				g_file_error_from_errno (errno),
59ad60
 				"%s: %s",
59ad60
 				_("Failed to copy the tmp file"),
59ad60
@@ -4702,7 +4673,20 @@ imapx_command_fetch_message_done (CamelI
59ad60
 		g_free (tmp_filename);
59ad60
 	}
59ad60
 
59ad60
-	camel_data_cache_remove (ifolder->cache, "tmp", data->uid, NULL);
59ad60
+	/* Delete the 'tmp' file only if the operation wasn't cancelled. It's because
59ad60
+	   cancelled operations end before they are properly finished (IMAP-protocol speaking),
59ad60
+	   thus if any other GET_MESSAGE operation was waiting for this job, then it
59ad60
+	   realized that the message was not downloaded and opened its own "tmp" file, but
59ad60
+	   of the same name, thus this remove would drop file which could be used
59ad60
+	   by a different GET_MESSAGE job. */
59ad60
+	if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
59ad60
+		camel_data_cache_remove (ifolder->cache, "tmp", data->uid, NULL);
59ad60
+
59ad60
+	/* Avoid possible use-after-free when the imapx_unregister_job() can
59ad60
+	   also free the 'job' structure. */
59ad60
+	if (local_error != NULL)
59ad60
+		camel_imapx_job_set_error (job, local_error);
59ad60
+
59ad60
 	imapx_unregister_job (is, job);
59ad60
 
59ad60
 exit:
59ad60
@@ -4710,6 +4694,9 @@ exit:
59ad60
 
59ad60
 	camel_imapx_command_unref (ic);
59ad60
 
59ad60
+	if (local_error)
59ad60
+		g_propagate_error (error, local_error);
59ad60
+
59ad60
 	return success;
59ad60
 }
59ad60
 
59ad60
@@ -4743,10 +4730,10 @@ imapx_job_get_message_start (CamelIMAPXJ
59ad60
 			camel_imapx_command_set_job (ic, job);
59ad60
 			ic->pri = job->pri;
59ad60
 			data->fetch_offset += MULTI_SIZE;
59ad60
-			job->commands++;
59ad60
+			g_atomic_int_add (&job->commands, 1);
59ad60
 
59ad60
 			success = imapx_command_queue (
59ad60
-				is, ic, cancellable, error);
59ad60
+				is, ic, error);
59ad60
 			if (!success)
59ad60
 				break;
59ad60
 		}
59ad60
@@ -4758,9 +4745,9 @@ imapx_job_get_message_start (CamelIMAPXJ
59ad60
 		ic->complete = imapx_command_fetch_message_done;
59ad60
 		camel_imapx_command_set_job (ic, job);
59ad60
 		ic->pri = job->pri;
59ad60
-		job->commands++;
59ad60
+		g_atomic_int_add (&job->commands, 1);
59ad60
 
59ad60
-		success = imapx_command_queue (is, ic, cancellable, error);
59ad60
+		success = imapx_command_queue (is, ic, error);
59ad60
 	}
59ad60
 
59ad60
 	g_object_unref (folder);
59ad60
@@ -4903,14 +4890,14 @@ imapx_command_copy_messages_step_start (
59ad60
 		if (res == 1) {
59ad60
 			camel_imapx_command_add (ic, " %f", data->dest);
59ad60
 			data->index = i + 1;
59ad60
-			return imapx_command_queue (is, ic, cancellable, error);
59ad60
+			return imapx_command_queue (is, ic, error);
59ad60
 		}
59ad60
 	}
59ad60
 
59ad60
 	data->index = i;
59ad60
 	if (imapx_uidset_done (&data->uidset, ic)) {
59ad60
 		camel_imapx_command_add (ic, " %f", data->dest);
59ad60
-		return imapx_command_queue (is, ic, cancellable, error);
59ad60
+		return imapx_command_queue (is, ic, error);
59ad60
 	}
59ad60
 
59ad60
 	return TRUE;
59ad60
@@ -5055,11 +5042,11 @@ imapx_job_append_message_start (CamelIMA
59ad60
 	ic->complete = imapx_command_append_message_done;
59ad60
 	camel_imapx_command_set_job (ic, job);
59ad60
 	ic->pri = job->pri;
59ad60
-	job->commands++;
59ad60
+	g_atomic_int_add (&job->commands, 1);
59ad60
 
59ad60
 	g_object_unref (folder);
59ad60
 
59ad60
-	return imapx_command_queue (is, ic, cancellable, error);
59ad60
+	return imapx_command_queue (is, ic, error);
59ad60
 }
59ad60
 
59ad60
 /* ********************************************************************** */
59ad60
@@ -5233,7 +5220,7 @@ imapx_command_step_fetch_done (CamelIMAP
59ad60
 
59ad60
 					g_object_unref (folder);
59ad60
 
59ad60
-					return imapx_command_queue (is, ic, cancellable, error);
59ad60
+					return imapx_command_queue (is, ic, error);
59ad60
 				}
59ad60
 			}
59ad60
 		}
59ad60
@@ -5245,7 +5232,7 @@ imapx_command_step_fetch_done (CamelIMAP
59ad60
 
59ad60
 			g_object_unref (folder);
59ad60
 
59ad60
-			return imapx_command_queue (is, ic, cancellable, error);
59ad60
+			return imapx_command_queue (is, ic, error);
59ad60
 		}
59ad60
 	}
59ad60
 
59ad60
@@ -5556,7 +5543,7 @@ imapx_job_scan_changes_start (CamelIMAPX
59ad60
 
59ad60
 	g_object_unref (folder);
59ad60
 
59ad60
-	return imapx_command_queue (is, ic, cancellable, error);
59ad60
+	return imapx_command_queue (is, ic, error);
59ad60
 }
59ad60
 
59ad60
 static gboolean
59ad60
@@ -5730,7 +5717,7 @@ imapx_job_fetch_new_messages_start (Came
59ad60
 
59ad60
 	g_object_unref (folder);
59ad60
 
59ad60
-	return imapx_command_queue (is, ic, cancellable, error);
59ad60
+	return imapx_command_queue (is, ic, error);
59ad60
 }
59ad60
 
59ad60
 static gboolean
59ad60
@@ -5863,7 +5850,7 @@ imapx_job_fetch_messages_start (CamelIMA
59ad60
 
59ad60
 	g_object_unref (folder);
59ad60
 
59ad60
-	return imapx_command_queue (is, ic, cancellable, error);
59ad60
+	return imapx_command_queue (is, ic, error);
59ad60
 }
59ad60
 
59ad60
 static gboolean
59ad60
@@ -6208,7 +6195,7 @@ imapx_job_expunge_start (CamelIMAPXJob *
59ad60
 		ic->pri = job->pri;
59ad60
 		ic->complete = imapx_command_expunge_done;
59ad60
 
59ad60
-		success = imapx_command_queue (is, ic, cancellable, error);
59ad60
+		success = imapx_command_queue (is, ic, error);
59ad60
 	}
59ad60
 
59ad60
 	g_object_unref (folder);
59ad60
@@ -6279,7 +6266,7 @@ imapx_job_list_start (CamelIMAPXJob *job
59ad60
 	camel_imapx_command_set_job (ic, job);
59ad60
 	ic->complete = imapx_command_list_done;
59ad60
 
59ad60
-	return imapx_command_queue (is, ic, cancellable, error);
59ad60
+	return imapx_command_queue (is, ic, error);
59ad60
 }
59ad60
 
59ad60
 static gboolean
59ad60
@@ -6368,7 +6355,7 @@ imapx_job_manage_subscription_start (Cam
59ad60
 
59ad60
 	g_object_unref (store);
59ad60
 
59ad60
-	return imapx_command_queue (is, ic, cancellable, error);
59ad60
+	return imapx_command_queue (is, ic, error);
59ad60
 }
59ad60
 
59ad60
 /* ********************************************************************** */
59ad60
@@ -6422,7 +6409,7 @@ imapx_job_create_folder_start (CamelIMAP
59ad60
 
59ad60
 	g_free (encoded_fname);
59ad60
 
59ad60
-	return imapx_command_queue (is, ic, cancellable, error);
59ad60
+	return imapx_command_queue (is, ic, error);
59ad60
 }
59ad60
 
59ad60
 /* ********************************************************************** */
59ad60
@@ -6487,7 +6474,7 @@ imapx_job_delete_folder_start (CamelIMAP
59ad60
 		camel_imapx_command_set_job (ic, job);
59ad60
 		ic->complete = imapx_command_delete_folder_done;
59ad60
 
59ad60
-		success = imapx_command_queue (is, ic, cancellable, error);
59ad60
+		success = imapx_command_queue (is, ic, error);
59ad60
 
59ad60
 		g_object_unref (folder);
59ad60
 	}
59ad60
@@ -6561,7 +6548,7 @@ imapx_job_rename_folder_start (CamelIMAP
59ad60
 		camel_imapx_command_set_job (ic, job);
59ad60
 		ic->complete = imapx_command_rename_folder_done;
59ad60
 
59ad60
-		success = imapx_command_queue (is, ic, cancellable, error);
59ad60
+		success = imapx_command_queue (is, ic, error);
59ad60
 
59ad60
 		g_object_unref (folder);
59ad60
 	}
59ad60
@@ -6628,7 +6615,7 @@ imapx_job_update_quota_info_start (Camel
59ad60
 	camel_imapx_command_set_job (ic, job);
59ad60
 	ic->complete = imapx_command_update_quota_info_done;
59ad60
 
59ad60
-	success = imapx_command_queue (is, ic, cancellable, error);
59ad60
+	success = imapx_command_queue (is, ic, error);
59ad60
 
59ad60
 	g_free (encoded_folder_name);
59ad60
 
59ad60
@@ -6699,7 +6686,7 @@ imapx_job_uid_search_start (CamelIMAPXJo
59ad60
 
59ad60
 	g_object_unref (folder);
59ad60
 
59ad60
-	return imapx_command_queue (is, ic, cancellable, error);
59ad60
+	return imapx_command_queue (is, ic, error);
59ad60
 }
59ad60
 
59ad60
 /* ********************************************************************** */
59ad60
@@ -6752,7 +6739,7 @@ imapx_job_noop_start (CamelIMAPXJob *job
59ad60
 		ic->pri = IMAPX_PRIORITY_NOOP;
59ad60
 	}
59ad60
 
59ad60
-	return imapx_command_queue (is, ic, cancellable, error);
59ad60
+	return imapx_command_queue (is, ic, error);
59ad60
 }
59ad60
 
59ad60
 /* ********************************************************************** */
59ad60
@@ -6810,7 +6797,7 @@ imapx_command_sync_changes_done (CamelIM
59ad60
 	mobile_mode = camel_imapx_settings_get_mobile_mode (settings);
59ad60
 	g_object_unref (settings);
59ad60
 
59ad60
-	job->commands--;
59ad60
+	g_atomic_int_add (&job->commands, -1);
59ad60
 
59ad60
 	full_name = camel_folder_get_full_name (folder);
59ad60
 	parent_store = camel_folder_get_parent_store (folder);
59ad60
@@ -6862,7 +6849,7 @@ imapx_command_sync_changes_done (CamelIM
59ad60
 		((CamelIMAPXFolder *) folder)->unread_on_server += data->unread_change;
59ad60
 	}
59ad60
 
59ad60
-	if (job->commands == 0) {
59ad60
+	if (g_atomic_int_get (&job->commands) == 0) {
59ad60
 		if (folder->summary && (folder->summary->flags & CAMEL_FOLDER_SUMMARY_DIRTY) != 0) {
59ad60
 			CamelStoreInfo *si;
59ad60
 
59ad60
@@ -6888,6 +6875,11 @@ imapx_command_sync_changes_done (CamelIM
59ad60
 		camel_store_summary_save ((CamelStoreSummary *)((CamelIMAPXStore *) parent_store)->summary);
59ad60
 
59ad60
 		imapx_unregister_job (is, job);
59ad60
+	} else {
59ad60
+		/* Make sure no command will starve in a queue */
59ad60
+		QUEUE_LOCK (is);
59ad60
+		imapx_command_start_next (is);
59ad60
+		QUEUE_UNLOCK (is);
59ad60
 	}
59ad60
 
59ad60
 	g_object_unref (folder);
59ad60
@@ -6974,9 +6966,9 @@ imapx_job_sync_changes_start (CamelIMAPX
59ad60
 					send = imapx_uidset_add (&ss, ic, camel_message_info_uid (info));
59ad60
 				}
59ad60
 				if (send == 1 || (i == uids->len - 1 && imapx_uidset_done (&ss, ic))) {
59ad60
-					job->commands++;
59ad60
+					g_atomic_int_add (&job->commands, 1);
59ad60
 					camel_imapx_command_add (ic, " %tFLAGS.SILENT (%t)", on?"+":"-", flags_table[j].name);
59ad60
-					if (!imapx_command_queue (is, ic, cancellable, error)) {
59ad60
+					if (!imapx_command_queue (is, ic, error)) {
59ad60
 						camel_message_info_free (info);
59ad60
 						goto exit;
59ad60
 					}
59ad60
@@ -7015,9 +7007,9 @@ imapx_job_sync_changes_start (CamelIMAPX
59ad60
 
59ad60
 					if (imapx_uidset_add (&ss, ic, camel_message_info_uid (info)) == 1
59ad60
 					    || (i == c->infos->len - 1 && imapx_uidset_done (&ss, ic))) {
59ad60
-						job->commands++;
59ad60
+						g_atomic_int_add (&job->commands, 1);
59ad60
 						camel_imapx_command_add (ic, " %tFLAGS.SILENT (%t)", on?"+":"-", c->name);
59ad60
-						if (!imapx_command_queue (is, ic, cancellable, error))
59ad60
+						if (!imapx_command_queue (is, ic, error))
59ad60
 							goto exit;
59ad60
 						ic = NULL;
59ad60
 					}
59ad60
@@ -7029,11 +7021,14 @@ imapx_job_sync_changes_start (CamelIMAPX
59ad60
 exit:
59ad60
 	g_object_unref (folder);
59ad60
 
59ad60
-	/* Since this may start in another thread ... we need to
59ad60
-	 * lock the commands count, ho hum */
59ad60
-
59ad60
-	if (job->commands == 0)
59ad60
+	if (g_atomic_int_get (&job->commands) == 0) {
59ad60
 		imapx_unregister_job (is, job);
59ad60
+	} else {
59ad60
+		/* Make sure no command will starve in a queue */
59ad60
+		QUEUE_LOCK (is);
59ad60
+		imapx_command_start_next (is);
59ad60
+		QUEUE_UNLOCK (is);
59ad60
+	}
59ad60
 
59ad60
 	return TRUE;
59ad60
 }
59ad60
@@ -7701,6 +7696,11 @@ imapx_server_get_message (CamelIMAPXServ
59ad60
 		return NULL;
59ad60
 	}
59ad60
 
59ad60
+	/* This makes sure that if any file is left on the disk, it is not reused.
59ad60
+	   That can happen when the previous message download had been cancelled
59ad60
+	   or finished with an error. */
59ad60
+	camel_data_cache_remove (ifolder->cache, "tmp", uid, NULL);
59ad60
+
59ad60
 	data = g_slice_new0 (GetMessageData);
59ad60
 	data->uid = g_strdup (uid);
59ad60
 	data->stream = camel_data_cache_add (ifolder->cache, "tmp", uid, NULL);
59ad60
@@ -8964,3 +8964,106 @@ camel_imapx_server_shutdown (CamelIMAPXS
59ad60
 	g_clear_object (&cancellable);
59ad60
 	g_clear_error (&shutdown_error_copy);
59ad60
 }
59ad60
+
59ad60
+static const gchar *
59ad60
+imapx_server_get_job_type_name (CamelIMAPXJob *job)
59ad60
+{
59ad60
+	if (!job)
59ad60
+		return "[null]";
59ad60
+
59ad60
+	switch (job->type) {
59ad60
+	case IMAPX_JOB_GET_MESSAGE:
59ad60
+		return "GET_MESSAGE";
59ad60
+	case IMAPX_JOB_APPEND_MESSAGE:
59ad60
+		return "APPEND_MESSAGE";
59ad60
+	case IMAPX_JOB_COPY_MESSAGE:
59ad60
+		return "COPY_MESSAGE";
59ad60
+	case IMAPX_JOB_FETCH_NEW_MESSAGES:
59ad60
+		return "FETCH_NEW_MESSAGES";
59ad60
+	case IMAPX_JOB_REFRESH_INFO:
59ad60
+		return "REFRESH_INFO";
59ad60
+	case IMAPX_JOB_SYNC_CHANGES:
59ad60
+		return "SYNC_CHANGES";
59ad60
+	case IMAPX_JOB_EXPUNGE:
59ad60
+		return "EXPUNGE";
59ad60
+	case IMAPX_JOB_NOOP:
59ad60
+		return "NOOP";
59ad60
+	case IMAPX_JOB_IDLE:
59ad60
+		return "IDLE";
59ad60
+	case IMAPX_JOB_LIST:
59ad60
+		return "LIST";
59ad60
+	case IMAPX_JOB_CREATE_FOLDER:
59ad60
+		return "CREATE_FOLDER";
59ad60
+	case IMAPX_JOB_DELETE_FOLDER:
59ad60
+		return "DELETE_FOLDER";
59ad60
+	case IMAPX_JOB_RENAME_FOLDER:
59ad60
+		return "RENAME_FOLDER";
59ad60
+	case IMAPX_JOB_MANAGE_SUBSCRIPTION:
59ad60
+		return "MANAGE_SUBSCRIPTION";
59ad60
+	case IMAPX_JOB_UPDATE_QUOTA_INFO:
59ad60
+		return "UPDATE_QUOTA_INFO";
59ad60
+	case IMAPX_JOB_UID_SEARCH:
59ad60
+		return "UID_SEARCH";
59ad60
+	}
59ad60
+
59ad60
+	return "???";
59ad60
+}
59ad60
+
59ad60
+static void
59ad60
+imapx_server_dump_one_queue (CamelIMAPXCommandQueue *queue,
59ad60
+			     const gchar *queue_name)
59ad60
+{
59ad60
+	GList *iter;
59ad60
+	gint ii;
59ad60
+
59ad60
+	g_return_if_fail (queue != NULL);
59ad60
+	g_return_if_fail (queue_name != NULL);
59ad60
+
59ad60
+	if (camel_imapx_command_queue_is_empty (queue))
59ad60
+		return;
59ad60
+
59ad60
+	printf ("      Content of '%s':\n", queue_name);
59ad60
+
59ad60
+	for (ii = 0, iter = camel_imapx_command_queue_peek_head_link (queue); iter != NULL; iter = g_list_next (iter), ii++) {
59ad60
+		CamelIMAPXCommand *ic = iter->data;
59ad60
+		CamelIMAPXJob *job = camel_imapx_command_get_job (ic);
59ad60
+
59ad60
+		printf ("         [%d] command:%p for job:%p (type:0x%x %s)\n", ii, ic, job, job ? job->type : 0, imapx_server_get_job_type_name (job));
59ad60
+	}
59ad60
+}
59ad60
+
59ad60
+/* for debugging purposes only */
59ad60
+void
59ad60
+camel_imapx_server_dump_queue_status (CamelIMAPXServer *imapx_server)
59ad60
+{
59ad60
+	g_return_if_fail (CAMEL_IS_IMAPX_SERVER (imapx_server));
59ad60
+
59ad60
+	QUEUE_LOCK (imapx_server);
59ad60
+
59ad60
+	printf ("   Queue status for server %p: jobs:%d queued:%d active:%d done:%d\n", imapx_server,
59ad60
+		g_queue_get_length (&imapx_server->jobs),
59ad60
+		camel_imapx_command_queue_get_length (imapx_server->queue),
59ad60
+		camel_imapx_command_queue_get_length (imapx_server->active),
59ad60
+		camel_imapx_command_queue_get_length (imapx_server->done));
59ad60
+
59ad60
+	if (!g_queue_is_empty (&imapx_server->jobs)) {
59ad60
+		GList *iter;
59ad60
+		gint ii;
59ad60
+
59ad60
+		printf ("      Content of 'jobs':\n");
59ad60
+
59ad60
+		for (ii = 0, iter = g_queue_peek_head_link (&imapx_server->jobs); iter != NULL; iter = g_list_next (iter), ii++) {
59ad60
+			CamelIMAPXJob *job = iter->data;
59ad60
+
59ad60
+			printf ("         [%d] job:%p (type:0x%x %s) with pending commands:%d\n", ii, job, job ? job->type : 0,
59ad60
+				imapx_server_get_job_type_name (job),
59ad60
+				job ? g_atomic_int_get (&job->commands) : -1);
59ad60
+		}
59ad60
+	}
59ad60
+
59ad60
+	imapx_server_dump_one_queue (imapx_server->queue, "queue");
59ad60
+	imapx_server_dump_one_queue (imapx_server->active, "active");
59ad60
+	imapx_server_dump_one_queue (imapx_server->done, "done");
59ad60
+
59ad60
+	QUEUE_UNLOCK (imapx_server);
59ad60
+}
59ad60
diff -up evolution-data-server-3.8.5/camel/camel-imapx-server.h.imapx-error-cancelled-message-download evolution-data-server-3.8.5/camel/camel-imapx-server.h
59ad60
--- evolution-data-server-3.8.5/camel/camel-imapx-server.h.imapx-error-cancelled-message-download	2014-05-16 11:36:17.875612926 +0200
59ad60
+++ evolution-data-server-3.8.5/camel/camel-imapx-server.h	2014-05-16 11:36:17.885612837 +0200
59ad60
@@ -312,6 +312,9 @@ struct _CamelIMAPXJob *
59ad60
 						 CamelFolder *folder,
59ad60
 						 guint32 job_type,
59ad60
 						 const gchar *uid);
59ad60
+/* for debugging purposes only */
59ad60
+void		camel_imapx_server_dump_queue_status
59ad60
+						(CamelIMAPXServer *imapx_server);
59ad60
 
59ad60
 G_END_DECLS
59ad60
 
59ad60
diff -up evolution-data-server-3.8.5/camel/camel-imapx-store.c.imapx-error-cancelled-message-download evolution-data-server-3.8.5/camel/camel-imapx-store.c
59ad60
--- evolution-data-server-3.8.5/camel/camel-imapx-store.c.imapx-error-cancelled-message-download	2014-05-16 11:36:17.876612917 +0200
59ad60
+++ evolution-data-server-3.8.5/camel/camel-imapx-store.c	2014-05-16 11:36:17.886612828 +0200
59ad60
@@ -2226,3 +2226,12 @@ camel_imapx_store_ref_job (CamelIMAPXSto
59ad60
 
59ad60
 	return job;
59ad60
 }
59ad60
+
59ad60
+/* for debugging purposes only */
59ad60
+void
59ad60
+camel_imapx_store_dump_queue_status (CamelIMAPXStore *imapx_store)
59ad60
+{
59ad60
+	g_return_if_fail (CAMEL_IS_IMAPX_STORE (imapx_store));
59ad60
+
59ad60
+	camel_imapx_conn_manager_dump_queue_status (imapx_store->con_man);
59ad60
+}
59ad60
diff -up evolution-data-server-3.8.5/camel/camel-imapx-store.h.imapx-error-cancelled-message-download evolution-data-server-3.8.5/camel/camel-imapx-store.h
59ad60
--- evolution-data-server-3.8.5/camel/camel-imapx-store.h.imapx-error-cancelled-message-download	2014-05-16 11:36:17.876612917 +0200
59ad60
+++ evolution-data-server-3.8.5/camel/camel-imapx-store.h	2014-05-16 11:36:17.886612828 +0200
59ad60
@@ -120,6 +120,9 @@ struct _CamelIMAPXJob *
59ad60
 						 CamelFolder *folder,
59ad60
 						 guint32 job_type,
59ad60
 						 const gchar *uid);
59ad60
+/* for debugging purposes only */
59ad60
+void		camel_imapx_store_dump_queue_status
59ad60
+						(CamelIMAPXStore *imapx_store);
59ad60
 
59ad60
 G_END_DECLS
59ad60