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;