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;