[evolution-data-server/gnome-3-18] [IMAPx] Prefer graceful IDLE stop than forced reconnect
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/gnome-3-18] [IMAPx] Prefer graceful IDLE stop than forced reconnect
- Date: Wed, 3 Feb 2016 09:39:20 +0000 (UTC)
commit 144e6d76c2fb653ae55287b7f02f8a83103f904f
Author: Milan Crha <mcrha redhat com>
Date: Wed Feb 3 10:32:24 2016 +0100
[IMAPx] Prefer graceful IDLE stop than forced reconnect
There still was an issue with stopping IDLE, the code could have run IDLE
in the preparation, like selecting the right folder, when it received
a request to stop IDLE and start other command. As the preparation was
not distinguished properly two commands could interleave and cause issues.
When in it, the IDLE stop had been done to stop it gracefully, instead
of disconnect the connection when in the middle of some command. It
should make things quicker (reconnect is slow), especially when the connection
is not stale.
camel/providers/imapx/camel-imapx-server.c | 77 +++++++++++++++-------------
1 files changed, 42 insertions(+), 35 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index eb6e85e..ecd89bc 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -5966,6 +5966,9 @@ imapx_server_idle_thread (gpointer user_data)
return NULL;
}
+ is->priv->idle_state = IMAPX_IDLE_STATE_PREPARING;
+ g_cond_broadcast (&is->priv->idle_cond);
+
mailbox = is->priv->idle_mailbox;
if (mailbox)
g_object_ref (mailbox);
@@ -5998,9 +6001,7 @@ imapx_server_idle_thread (gpointer user_data)
g_mutex_lock (&is->priv->idle_lock);
if (is->priv->idle_stamp == itd->idle_stamp &&
- is->priv->idle_state == IMAPX_IDLE_STATE_SCHEDULED) {
- is->priv->idle_state = IMAPX_IDLE_STATE_PREPARING;
- g_cond_broadcast (&is->priv->idle_cond);
+ is->priv->idle_state == IMAPX_IDLE_STATE_PREPARING) {
g_mutex_unlock (&is->priv->idle_lock);
/* Blocks, until the DONE is issued or on inactivity timeout, error, ... */
@@ -6230,8 +6231,7 @@ camel_imapx_server_stop_idle_sync (CamelIMAPXServer *is,
GError **error)
{
GCancellable *idle_cancellable;
- gboolean issue_done = FALSE;
- gboolean rather_disconnect = FALSE;
+ gulong handler_id = 0;
gboolean success = TRUE;
g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
@@ -6249,16 +6249,7 @@ camel_imapx_server_stop_idle_sync (CamelIMAPXServer *is,
}
is->priv->idle_state = IMAPX_IDLE_STATE_OFF;
- } else if (is->priv->idle_state == IMAPX_IDLE_STATE_PREPARING) {
- success = FALSE;
-
- /* This message won't get into UI. */
- g_set_error_literal (error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT,
- "Reconnect after preparing IDLE command");
- } else if (is->priv->idle_state == IMAPX_IDLE_STATE_RUNNING) {
- is->priv->idle_state = IMAPX_IDLE_STATE_STOPPING;
g_cond_broadcast (&is->priv->idle_cond);
- issue_done = TRUE;
}
idle_cancellable = is->priv->idle_cancellable ? g_object_ref (is->priv->idle_cancellable) : NULL;
@@ -6267,9 +6258,20 @@ camel_imapx_server_stop_idle_sync (CamelIMAPXServer *is,
g_clear_object (&is->priv->idle_mailbox);
is->priv->idle_stamp++;
- g_mutex_unlock (&is->priv->idle_lock);
+ if (cancellable)
+ handler_id = g_cancellable_connect (cancellable, G_CALLBACK
(imapx_server_wait_idle_stop_cancelled_cb), is, NULL);
+
+ while (is->priv->idle_state == IMAPX_IDLE_STATE_PREPARING &&
+ !g_cancellable_is_cancelled (cancellable)) {
+ g_cond_wait (&is->priv->idle_cond, &is->priv->idle_lock);
+ }
+
+ if (is->priv->idle_state == IMAPX_IDLE_STATE_RUNNING &&
+ !g_cancellable_is_cancelled (cancellable)) {
+ is->priv->idle_state = IMAPX_IDLE_STATE_STOPPING;
+ g_cond_broadcast (&is->priv->idle_cond);
+ g_mutex_unlock (&is->priv->idle_lock);
- if (issue_done) {
g_mutex_lock (&is->priv->stream_lock);
if (is->priv->output_stream) {
gint previous_timeout = -1;
@@ -6292,33 +6294,38 @@ camel_imapx_server_stop_idle_sync (CamelIMAPXServer *is,
"Reconnect after couldn't issue DONE command");
}
g_mutex_unlock (&is->priv->stream_lock);
+ g_mutex_lock (&is->priv->idle_lock);
}
- if (success) {
- gulong handler_id = 0;
+ while (success && is->priv->idle_state != IMAPX_IDLE_STATE_OFF &&
+ !g_cancellable_is_cancelled (cancellable)) {
+ g_cond_wait (&is->priv->idle_cond, &is->priv->idle_lock);
+ }
- if (cancellable)
- handler_id = g_cancellable_connect (cancellable, G_CALLBACK
(imapx_server_wait_idle_stop_cancelled_cb), is, NULL);
+ if (cancellable && handler_id)
+ g_cancellable_disconnect (cancellable, handler_id);
- g_mutex_lock (&is->priv->idle_lock);
- while (is->priv->idle_state != IMAPX_IDLE_STATE_OFF &&
- !g_cancellable_set_error_if_cancelled (cancellable, error)) {
- g_cond_wait (&is->priv->idle_cond, &is->priv->idle_lock);
- }
- g_mutex_unlock (&is->priv->idle_lock);
+ if (success && g_cancellable_is_cancelled (cancellable)) {
+ g_clear_error (error);
- if (cancellable && handler_id)
- g_cancellable_disconnect (cancellable, handler_id);
- } else {
+ success = FALSE;
+
+ /* This message won't get into UI. */
+ g_set_error_literal (error, CAMEL_IMAPX_SERVER_ERROR, CAMEL_IMAPX_SERVER_ERROR_TRY_RECONNECT,
+ "Reconnect after cancelled IDLE stop command");
+ }
+
+ g_mutex_unlock (&is->priv->idle_lock);
+
+ if (!success) {
if (idle_cancellable)
g_cancellable_cancel (idle_cancellable);
- if (rather_disconnect) {
- g_mutex_lock (&is->priv->idle_lock);
- is->priv->idle_state = IMAPX_IDLE_STATE_OFF;
- g_mutex_unlock (&is->priv->idle_lock);
- imapx_disconnect (is);
- }
+ g_mutex_lock (&is->priv->idle_lock);
+ is->priv->idle_state = IMAPX_IDLE_STATE_OFF;
+ g_mutex_unlock (&is->priv->idle_lock);
+
+ imapx_disconnect (is);
}
g_clear_object (&idle_cancellable);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]