diff -up evolution-data-server-3.8.5/camel/camel-imapx-command.c.imapx-summary-vanish evolution-data-server-3.8.5/camel/camel-imapx-command.c --- evolution-data-server-3.8.5/camel/camel-imapx-command.c.imapx-summary-vanish 2013-08-02 16:57:28.000000000 +0200 +++ evolution-data-server-3.8.5/camel/camel-imapx-command.c 2013-10-09 12:49:22.007984356 +0200 @@ -42,6 +42,9 @@ struct _CamelIMAPXRealCommand { /* For building the part. */ GString *buffer; + /* For network/parse errors. */ + GError *error; + /* Used for running some commands synchronously. */ GCond done_sync_cond; GMutex done_sync_mutex; @@ -141,6 +144,8 @@ camel_imapx_command_unref (CamelIMAPXCom g_string_free (real_ic->buffer, TRUE); + g_clear_error (&real_ic->error); + g_cond_clear (&real_ic->done_sync_cond); g_mutex_clear (&real_ic->done_sync_mutex); @@ -577,12 +582,50 @@ camel_imapx_command_done (CamelIMAPXComm g_mutex_unlock (&real_ic->done_sync_mutex); } +/** + * camel_imapx_command_failed: + * @ic: a #CamelIMAPXCommand + * @error: the error which caused the failure + * + * Copies @error to be returned in camel_imapx_command_set_error_if_failed(). + * Call this function if a networking or parsing error occurred to force all + * active IMAP commands to abort processing. + * + * Since: 3.10 + **/ +void +camel_imapx_command_failed (CamelIMAPXCommand *ic, + const GError *error) +{ + CamelIMAPXRealCommand *real_ic; + + g_return_if_fail (CAMEL_IS_IMAPX_COMMAND (ic)); + g_return_if_fail (error != NULL); + + real_ic = (CamelIMAPXRealCommand *) ic; + g_return_if_fail (real_ic->error == NULL); + + real_ic->error = g_error_copy (error); +} + gboolean camel_imapx_command_set_error_if_failed (CamelIMAPXCommand *ic, GError **error) { + CamelIMAPXRealCommand *real_ic; + g_return_val_if_fail (CAMEL_IS_IMAPX_COMMAND (ic), FALSE); + real_ic = (CamelIMAPXRealCommand *) ic; + + /* Check for a networking or parsing error. */ + if (real_ic->error != NULL) { + g_propagate_error (error, real_ic->error); + real_ic->error = NULL; + return TRUE; + } + + /* Check if the IMAP server rejected the command. */ if (ic->status != NULL && ic->status->result != IMAPX_OK) { /* FIXME Map IMAP response codes to more diff -up evolution-data-server-3.8.5/camel/camel-imapx-command.h.imapx-summary-vanish evolution-data-server-3.8.5/camel/camel-imapx-command.h --- evolution-data-server-3.8.5/camel/camel-imapx-command.h.imapx-summary-vanish 2013-07-23 13:57:42.000000000 +0200 +++ evolution-data-server-3.8.5/camel/camel-imapx-command.h 2013-10-09 12:49:22.008984356 +0200 @@ -120,6 +120,8 @@ void camel_imapx_command_add_part (Came void camel_imapx_command_close (CamelIMAPXCommand *ic); void camel_imapx_command_wait (CamelIMAPXCommand *ic); void camel_imapx_command_done (CamelIMAPXCommand *ic); +void camel_imapx_command_failed (CamelIMAPXCommand *ic, + const GError *error); gboolean camel_imapx_command_set_error_if_failed (CamelIMAPXCommand *ic, GError **error); diff -up evolution-data-server-3.8.5/camel/camel-imapx-server.c.imapx-summary-vanish evolution-data-server-3.8.5/camel/camel-imapx-server.c --- evolution-data-server-3.8.5/camel/camel-imapx-server.c.imapx-summary-vanish 2013-07-23 13:57:58.000000000 +0200 +++ evolution-data-server-3.8.5/camel/camel-imapx-server.c 2013-10-09 12:49:22.011984355 +0200 @@ -6795,10 +6795,9 @@ imapx_job_sync_changes_matches (CamelIMA return camel_imapx_job_has_folder (job, folder); } -/* we cancel all the commands and their jobs, so associated jobs will be notified */ static void -cancel_all_jobs (CamelIMAPXServer *is, - GError *error) +imapx_abort_all_commands (CamelIMAPXServer *is, + const GError *error) { CamelIMAPXCommandQueue *queue; GList *head, *link; @@ -6819,7 +6818,6 @@ cancel_all_jobs (CamelIMAPXServer *is, for (link = head; link != NULL; link = g_list_next (link)) { CamelIMAPXCommand *ic = link->data; - CamelIMAPXJob *job; /* Sanity check the CamelIMAPXCommand before proceeding. * XXX We are actually getting reports of crashes here... @@ -6827,17 +6825,15 @@ cancel_all_jobs (CamelIMAPXServer *is, if (ic == NULL) continue; - /* Similarly with the CamelIMAPXJob contained within. */ - job = camel_imapx_command_get_job (ic); - if (!CAMEL_IS_IMAPX_JOB (job)) - continue; - - camel_imapx_job_cancel (job); - - /* Send a NULL GError since we already cancelled - * the job and we're not interested in individual - * command errors. */ - ic->complete (is, ic, camel_imapx_job_get_cancellable (job), NULL); + /* Insert an error into the CamelIMAPXCommand to be + * propagated when the completion callback function + * calls camel_imapx_command_set_error_if_failed(). */ + camel_imapx_command_failed (ic, error); + + /* Invoke the completion callback function so it can + * perform any cleanup processing and unregister its + * CamelIMAPXJob. */ + ic->complete (is, ic, NULL, NULL); } camel_imapx_command_queue_free (queue); @@ -6963,7 +6959,7 @@ imapx_parser_thread (gpointer d) is->state = IMAPX_SHUTDOWN; QUEUE_UNLOCK (is); - cancel_all_jobs (is, local_error); + imapx_abort_all_commands (is, local_error); g_clear_error (&local_error); diff -up evolution-data-server-3.8.5/docs/reference/camel/camel-sections.txt.imapx-summary-vanish evolution-data-server-3.8.5/docs/reference/camel/camel-sections.txt --- evolution-data-server-3.8.5/docs/reference/camel/camel-sections.txt.imapx-summary-vanish 2013-08-11 13:26:25.000000000 +0200 +++ evolution-data-server-3.8.5/docs/reference/camel/camel-sections.txt 2013-10-09 12:49:22.012984355 +0200 @@ -754,6 +754,7 @@ camel_imapx_command_add_part camel_imapx_command_close camel_imapx_command_wait camel_imapx_command_done +camel_imapx_command_failed camel_imapx_command_set_error_if_failed CamelIMAPXCommandQueue camel_imapx_command_queue_new