Blob Blame History Raw
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.c.imapx-msg-download-indefinite-wait evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.c
--- evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.c.imapx-msg-download-indefinite-wait	2015-06-01 21:47:39.859412175 +0200
+++ evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.c	2015-06-01 21:48:23.891134658 +0200
@@ -46,6 +46,8 @@ struct _CamelIMAPXRealJob {
 
 	CamelIMAPXMailbox *mailbox;
 	GMutex mailbox_lock;
+
+	CamelIMAPXMailbox *guard_mailbox_update; /* uses the mailbox_lock */
 };
 
 static void
@@ -124,6 +126,13 @@ camel_imapx_job_unref (CamelIMAPXJob *jo
 		if (real_job->destroy_data != NULL)
 			real_job->destroy_data (real_job->data);
 
+		g_mutex_lock (&real_job->mailbox_lock);
+		if (real_job->guard_mailbox_update) {
+			camel_imapx_mailbox_unlock_update (real_job->guard_mailbox_update);
+			g_clear_object (&real_job->guard_mailbox_update);
+		}
+		g_mutex_unlock (&real_job->mailbox_lock);
+
 		g_clear_object (&real_job->mailbox);
 		g_mutex_clear (&real_job->mailbox_lock);
 
@@ -232,6 +241,13 @@ camel_imapx_job_done (CamelIMAPXJob *job
 
 	real_job = (CamelIMAPXRealJob *) job;
 
+	g_mutex_lock (&real_job->mailbox_lock);
+	if (real_job->guard_mailbox_update) {
+		camel_imapx_mailbox_unlock_update (real_job->guard_mailbox_update);
+		g_clear_object (&real_job->guard_mailbox_update);
+	}
+	g_mutex_unlock (&real_job->mailbox_lock);
+
 	g_mutex_lock (&real_job->done_mutex);
 	real_job->done_flag = TRUE;
 	g_cond_broadcast (&real_job->done_cond);
@@ -263,6 +279,36 @@ camel_imapx_job_run (CamelIMAPXJob *job,
 	return success;
 }
 
+void
+camel_imapx_job_guard_mailbox_update (CamelIMAPXJob *job,
+				      CamelIMAPXMailbox *mailbox)
+{
+	CamelIMAPXRealJob *real_job;
+
+	g_return_if_fail (CAMEL_IS_IMAPX_JOB (job));
+
+	if (mailbox)
+		g_return_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox));
+
+	real_job = (CamelIMAPXRealJob *) job;
+
+	g_mutex_lock (&real_job->mailbox_lock);
+
+	if (mailbox != real_job->guard_mailbox_update) {
+		if (real_job->guard_mailbox_update) {
+			camel_imapx_mailbox_unlock_update (real_job->guard_mailbox_update);
+			g_clear_object (&real_job->guard_mailbox_update);
+		}
+
+		if (mailbox) {
+			real_job->guard_mailbox_update = g_object_ref (mailbox);
+			camel_imapx_mailbox_lock_update (real_job->guard_mailbox_update);
+		}
+	}
+
+	g_mutex_unlock (&real_job->mailbox_lock);
+}
+
 gboolean
 camel_imapx_job_matches (CamelIMAPXJob *job,
                          CamelIMAPXMailbox *mailbox,
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.h.imapx-msg-download-indefinite-wait evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.h
--- evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.h.imapx-msg-download-indefinite-wait	2015-06-01 21:47:45.811374376 +0200
+++ evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-job.h	2015-06-01 21:48:23.891134658 +0200
@@ -64,6 +64,9 @@ void		camel_imapx_job_done		(CamelIMAPXJ
 gboolean	camel_imapx_job_run		(CamelIMAPXJob *job,
 						 CamelIMAPXServer *is,
 						 GError **error);
+void		camel_imapx_job_guard_mailbox_update
+						(CamelIMAPXJob *job,
+						 CamelIMAPXMailbox *mailbox);
 gboolean	camel_imapx_job_matches		(CamelIMAPXJob *job,
 						 CamelIMAPXMailbox *mailbox,
 						 const gchar *uid);
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-mailbox.c.imapx-msg-download-indefinite-wait evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-mailbox.c
--- evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-mailbox.c.imapx-msg-download-indefinite-wait	2015-06-01 21:48:14.947190662 +0200
+++ evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-mailbox.c	2015-06-01 21:48:23.892134652 +0200
@@ -51,7 +51,9 @@ struct _CamelIMAPXMailboxPrivate {
 	CamelIMAPXMailboxState state;
 
 	GMutex property_lock;
-	GRecMutex update_lock;
+	GMutex update_lock;
+	GCond update_cond;
+	gboolean update_is_locked;
 
 	/* Protected by the "property_lock". */
 	GHashTable *attributes;
@@ -98,7 +100,8 @@ imapx_mailbox_finalize (GObject *object)
 	g_free (priv->name);
 
 	g_mutex_clear (&priv->property_lock);
-	g_rec_mutex_clear (&priv->update_lock);
+	g_mutex_clear (&priv->update_lock);
+	g_cond_clear (&priv->update_cond);
 	g_hash_table_destroy (priv->attributes);
 	g_sequence_free (priv->message_map);
 	g_strfreev (priv->quota_roots);
@@ -125,7 +128,9 @@ camel_imapx_mailbox_init (CamelIMAPXMail
 	mailbox->priv = CAMEL_IMAPX_MAILBOX_GET_PRIVATE (mailbox);
 
 	g_mutex_init (&mailbox->priv->property_lock);
-	g_rec_mutex_init (&mailbox->priv->update_lock);
+	g_mutex_init (&mailbox->priv->update_lock);
+	g_cond_init (&mailbox->priv->update_cond);
+	mailbox->priv->update_is_locked = FALSE;
 	mailbox->priv->message_map = g_sequence_new (NULL);
 	mailbox->priv->permanentflags = ~0;
 	mailbox->priv->state = CAMEL_IMAPX_MAILBOX_STATE_CREATED;
@@ -1198,7 +1203,15 @@ camel_imapx_mailbox_lock_update (CamelIM
 {
 	g_return_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox));
 
-	g_rec_mutex_lock (&mailbox->priv->update_lock);
+	g_mutex_lock (&mailbox->priv->update_lock);
+
+	while (mailbox->priv->update_is_locked) {
+		g_cond_wait (&mailbox->priv->update_cond, &mailbox->priv->update_lock);
+	}
+
+	mailbox->priv->update_is_locked = TRUE;
+
+	g_mutex_unlock (&mailbox->priv->update_lock);
 }
 
 /* Prevents running FETCH and STORE at the same time for the given mailbox */
@@ -1207,5 +1220,12 @@ camel_imapx_mailbox_unlock_update (Camel
 {
 	g_return_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox));
 
-	g_rec_mutex_unlock (&mailbox->priv->update_lock);
+	g_mutex_lock (&mailbox->priv->update_lock);
+
+	if (mailbox->priv->update_is_locked) {
+		mailbox->priv->update_is_locked = FALSE;
+		g_cond_signal (&mailbox->priv->update_cond);
+	}
+
+	g_mutex_unlock (&mailbox->priv->update_lock);
 }
diff -up evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.c.imapx-msg-download-indefinite-wait evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.c
--- evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.c.imapx-msg-download-indefinite-wait	2015-06-01 21:47:18.219550493 +0200
+++ evolution-data-server-3.12.11/camel/providers/imapx/camel-imapx-server.c	2015-06-01 21:48:23.895134633 +0200
@@ -1031,8 +1031,7 @@ static void
 imapx_unregister_job (CamelIMAPXServer *is,
                       CamelIMAPXJob *job)
 {
-	if (!job->noreply)
-		camel_imapx_job_done (job);
+	camel_imapx_job_done (job);
 
 	QUEUE_LOCK (is);
 
@@ -1051,10 +1050,17 @@ imapx_submit_job (CamelIMAPXServer *is,
                   CamelIMAPXJob *job,
                   GError **error)
 {
+	gboolean success;
+
 	if (!imapx_register_job (is, job, error))
 		return FALSE;
 
-	return camel_imapx_job_run (job, is, error);
+	success = camel_imapx_job_run (job, is, error);
+
+	if (!success)
+		imapx_unregister_job (is, job);
+
+	return success;
 }
 
 static CamelFolder *
@@ -7699,6 +7705,27 @@ imapx_abort_all_commands (CamelIMAPXServ
 	}
 
 	camel_imapx_command_queue_free (queue);
+
+	QUEUE_LOCK (is);
+
+	/* Abort also any pending jobs which are not in the command queues yet */
+	if (!g_queue_is_empty (&is->jobs)) {
+		GList *jobs, *iter;
+
+		jobs = g_list_copy (g_queue_peek_head_link (&is->jobs));
+		g_list_foreach (jobs, (GFunc) camel_imapx_job_ref, NULL);
+
+		for (iter = jobs; iter != NULL; iter = g_list_next (iter)) {
+			CamelIMAPXJob *job = iter->data;
+
+			camel_imapx_job_take_error (job, g_error_copy (error));
+			camel_imapx_job_done (job);
+		}
+
+		g_list_free_full (jobs, (GDestroyNotify) camel_imapx_job_unref);
+	}
+
+	QUEUE_UNLOCK (is);
 }
 
 /* ********************************************************************** */
@@ -8461,6 +8488,8 @@ imapx_server_get_message (CamelIMAPXServ
 
 	if (registered && camel_imapx_job_run (job, is, error))
 		stream = camel_stream_new (data->stream);
+	else if (registered)
+		imapx_unregister_job (is, job);
 
 	camel_imapx_job_unref (job);
 
@@ -8820,16 +8849,15 @@ camel_imapx_server_refresh_info (CamelIM
 	QUEUE_UNLOCK (is);
 
 	if (registered)
-		camel_imapx_mailbox_lock_update (mailbox);
+		camel_imapx_job_guard_mailbox_update (job, mailbox);
 
 	if (registered && camel_imapx_job_run (job, is, error)) {
 		changes = data->changes;
 		data->changes = NULL;
+	} else if (registered) {
+		imapx_unregister_job (is, job);
 	}
 
-	if (registered)
-		camel_imapx_mailbox_unlock_update (mailbox);
-
 	camel_imapx_job_unref (job);
 
 	return changes;
@@ -9158,12 +9186,12 @@ imapx_server_sync_changes (CamelIMAPXSer
 	QUEUE_UNLOCK (is);
 
 	if (job_type == IMAPX_JOB_SYNC_CHANGES && registered)
-		camel_imapx_mailbox_lock_update (mailbox);
+		camel_imapx_job_guard_mailbox_update (job, mailbox);
 
 	success = registered && camel_imapx_job_run (job, is, error);
 
-	if (job_type == IMAPX_JOB_SYNC_CHANGES && registered)
-		camel_imapx_mailbox_unlock_update (mailbox);
+	if (!success && registered)
+		imapx_unregister_job (is, job);
 
 	camel_imapx_job_unref (job);
 
@@ -9226,6 +9254,9 @@ camel_imapx_server_expunge (CamelIMAPXSe
 
 	success = registered && camel_imapx_job_run (job, is, error);
 
+	if (!success && registered)
+		imapx_unregister_job (is, job);
+
 	camel_imapx_job_unref (job);
 
 	return success;