diff options
Diffstat (limited to 'camel/providers/imapx/camel-imapx-server.c')
-rw-r--r-- | camel/providers/imapx/camel-imapx-server.c | 91 |
1 files changed, 39 insertions, 52 deletions
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c index b28c4be38..4c6b1d0db 100644 --- a/camel/providers/imapx/camel-imapx-server.c +++ b/camel/providers/imapx/camel-imapx-server.c @@ -5917,8 +5917,17 @@ imapx_server_idle_thread (gpointer user_data) previous_timeout = imapx_server_set_connection_timeout (is->priv->connection, INACTIVITY_TIMEOUT_SECONDS + 60); g_mutex_unlock (&is->priv->stream_lock); - /* Blocks, until the DONE is issued or on inactivity timeout, error, ... */ - success = camel_imapx_server_process_command_sync (is, ic, _("Error running IDLE"), idle_cancellable, &local_error); + g_rec_mutex_lock (&is->priv->idle_lock); + if (is->priv->idle_stamp == itd->idle_stamp) { + g_rec_mutex_unlock (&is->priv->idle_lock); + + /* Blocks, until the DONE is issued or on inactivity timeout, error, ... */ + success = camel_imapx_server_process_command_sync (is, ic, _("Error running IDLE"), idle_cancellable, &local_error); + + rather_disconnect = rather_disconnect || !success || g_cancellable_is_cancelled (idle_cancellable); + } else { + g_rec_mutex_unlock (&is->priv->idle_lock); + } if (previous_timeout >= 0) { g_mutex_lock (&is->priv->stream_lock); @@ -5935,11 +5944,11 @@ imapx_server_idle_thread (gpointer user_data) g_rec_mutex_unlock (&is->priv->idle_lock); if (success) - c (camel_imapx_server_get_tagprefix (is), "IDLE finished successfully"); + c (camel_imapx_server_get_tagprefix (is), "IDLE finished successfully\n"); else if (local_error) - c (camel_imapx_server_get_tagprefix (is), "IDLE finished with error: %s%s", local_error->message, rather_disconnect ? "; rather disconnect" : ""); + c (camel_imapx_server_get_tagprefix (is), "IDLE finished with error: %s%s\n", local_error->message, rather_disconnect ? "; rather disconnect" : ""); else - c (camel_imapx_server_get_tagprefix (is), "IDLE finished without error%s", rather_disconnect ? "; rather disconnect" : ""); + c (camel_imapx_server_get_tagprefix (is), "IDLE finished without error%s\n", rather_disconnect ? "; rather disconnect" : ""); if (rather_disconnect) { imapx_disconnect (is); @@ -6141,64 +6150,42 @@ camel_imapx_server_stop_idle_sync (CamelIMAPXServer *is, g_rec_mutex_unlock (&is->priv->idle_lock); - if (idle_cancellable) { - g_cancellable_cancel (idle_cancellable); - g_object_unref (idle_cancellable); - } - - if (idle_thread) - g_thread_join (idle_thread); - if (idle_command) { - CamelIMAPXCommand *ic; - gint previous_timeout = -1; - GError *local_error = NULL; - - g_return_val_if_fail (is->priv->current_command == NULL, FALSE); - - ic = camel_imapx_command_new (is, CAMEL_IMAPX_JOB_DONE, "DONE"); - ic->tag = idle_command->tag; - g_mutex_lock (&is->priv->stream_lock); - /* Set the connection timeout to some short time, no need to wait for it for too long */ - if (is->priv->connection) - previous_timeout = imapx_server_set_connection_timeout (is->priv->connection, 15); - g_mutex_unlock (&is->priv->stream_lock); - - success = camel_imapx_server_process_command_sync (is, ic, _("Failed to issue DONE"), cancellable, &local_error); + if (is->priv->output_stream) { + gint previous_timeout = -1; - if (previous_timeout >= 0) { - g_mutex_lock (&is->priv->stream_lock); + /* Set the connection timeout to some short time, no need to wait for it for too long */ if (is->priv->connection) - imapx_server_set_connection_timeout (is->priv->connection, previous_timeout); - g_mutex_unlock (&is->priv->stream_lock); - } + previous_timeout = imapx_server_set_connection_timeout (is->priv->connection, 5); - camel_imapx_command_unref (ic); - camel_imapx_command_unref (idle_command); + success = g_output_stream_flush (is->priv->output_stream, cancellable, error); + success = success && g_output_stream_write_all (is->priv->output_stream, "DONE\r\n", 6, NULL, cancellable, error); + success = success && g_output_stream_flush (is->priv->output_stream, cancellable, error); - if (success) - c (camel_imapx_server_get_tagprefix (is), "DONE finished successfully\n"); - else - c (camel_imapx_server_get_tagprefix (is), "DONE finished with error: %s\n", local_error ? local_error->message : "Unknown error"); + if (previous_timeout >= 0 && is->priv->connection) + imapx_server_set_connection_timeout (is->priv->connection, previous_timeout); + } else { + success = FALSE; - if (!success) { - GError *tmp = local_error; + /* This message won't get into UI. */ + g_set_error_literal (error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT, + "Reconnect after couldn't issue DONE command"); + } + g_mutex_unlock (&is->priv->stream_lock); - local_error = NULL; + camel_imapx_command_unref (idle_command); + } - g_set_error ( - &local_error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT, - "Failed to finish IDLE with DONE: %s", tmp ? tmp->message : "Unknown error"); + if ((!idle_command || !success) && idle_cancellable) { + g_cancellable_cancel (idle_cancellable); + } - g_clear_error (&tmp); - } + if (idle_cancellable) + g_object_unref (idle_cancellable); - if (local_error) { - g_propagate_error (error, local_error); - success = FALSE; - } - } + if (idle_thread) + g_thread_join (idle_thread); return success; } |