From 8894b72f2045388990b5696f3e8db97b9544ccf4 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 27 Jun 2011 15:23:31 +0200 Subject: Keep opening EClient-s till they report busy error --- modules/calendar/e-cal-shell-content.c | 1 - modules/calendar/e-cal-shell-sidebar.c | 96 ++++++++++++++++++++++++++++----- modules/calendar/e-memo-shell-sidebar.c | 95 +++++++++++++++++++++++++++----- modules/calendar/e-task-shell-sidebar.c | 95 +++++++++++++++++++++++++++----- 4 files changed, 250 insertions(+), 37 deletions(-) (limited to 'modules') diff --git a/modules/calendar/e-cal-shell-content.c b/modules/calendar/e-cal-shell-content.c index e85f9201cc..b4297b9fcd 100644 --- a/modules/calendar/e-cal-shell-content.c +++ b/modules/calendar/e-cal-shell-content.c @@ -279,7 +279,6 @@ cal_shell_content_dispose (GObject *object) } if (priv->calendar != NULL) { - gnome_calendar_dispose (GNOME_CALENDAR (priv->calendar)); g_object_unref (priv->calendar); priv->calendar = NULL; } diff --git a/modules/calendar/e-cal-shell-sidebar.c b/modules/calendar/e-cal-shell-sidebar.c index e33a7dcd06..efa233e019 100644 --- a/modules/calendar/e-cal-shell-sidebar.c +++ b/modules/calendar/e-cal-shell-sidebar.c @@ -59,6 +59,7 @@ struct _ECalShellSidebarPrivate { ECalClient *default_client; GCancellable *loading_default_client; + GCancellable *loading_clients; }; enum { @@ -181,6 +182,28 @@ cal_shell_sidebar_retrieve_capabilies_cb (GObject *source_object, GAsyncResult * cal_shell_sidebar_emit_status_message (cal_shell_sidebar, NULL); } +static gboolean cal_shell_sidebar_retry_open_timeout_cb (gpointer user_data); + +struct RetryOpenData +{ + EClient *client; + ECalShellSidebar *cal_shell_sidebar; + GCancellable *cancellable; +}; + +static void +free_retry_open_data (gpointer data) +{ + struct RetryOpenData *rod = data; + + if (!rod) + return; + + g_object_unref (rod->client); + g_object_unref (rod->cancellable); + g_free (rod); +} + static void cal_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { @@ -191,22 +214,44 @@ cal_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *result EShellSidebar *shell_sidebar; GError *error = NULL; - shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar); - shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); - shell_content = e_shell_view_get_shell_content (shell_view); - e_client_open_finish (E_CLIENT (client), result, &error); + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_clear_error (&error); + return; + } + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED) || g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_REQUIRED)) e_client_utils_forget_password (E_CLIENT (client)); if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED)) { - e_client_open (E_CLIENT (client), FALSE, NULL, cal_shell_sidebar_client_opened_cb, user_data); + e_client_open (E_CLIENT (client), FALSE, cal_shell_sidebar->priv->loading_clients, cal_shell_sidebar_client_opened_cb, user_data); + g_clear_error (&error); return; } + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_BUSY)) { + struct RetryOpenData *rod; + + rod = g_new0 (struct RetryOpenData, 1); + rod->client = g_object_ref (client); + rod->cal_shell_sidebar = cal_shell_sidebar; + rod->cancellable = g_object_ref (cal_shell_sidebar->priv->loading_clients); + + /* postpone for 1/2 of a second, backend is busy now */ + g_timeout_add_full (G_PRIORITY_DEFAULT, 500, cal_shell_sidebar_retry_open_timeout_cb, rod, free_retry_open_data); + + g_clear_error (&error); + return; + } + + shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_content = e_shell_view_get_shell_content (shell_view); + /* Handle errors. */ switch ((error && error->domain == E_CLIENT_ERROR) ? error->code : -1) { case -1: @@ -245,6 +290,24 @@ cal_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *result e_client_retrieve_capabilities (E_CLIENT (client), NULL, cal_shell_sidebar_retrieve_capabilies_cb, cal_shell_sidebar); } +static gboolean +cal_shell_sidebar_retry_open_timeout_cb (gpointer user_data) +{ + struct RetryOpenData *rod = user_data; + + g_return_val_if_fail (rod != NULL, FALSE); + g_return_val_if_fail (rod->client != NULL, FALSE); + g_return_val_if_fail (rod->cal_shell_sidebar != NULL, FALSE); + g_return_val_if_fail (rod->cancellable != NULL, FALSE); + + if (g_cancellable_is_cancelled (rod->cancellable)) + return FALSE; + + e_client_open (rod->client, FALSE, rod->cal_shell_sidebar->priv->loading_clients, cal_shell_sidebar_client_opened_cb, rod->cal_shell_sidebar); + + return FALSE; +} + static void cal_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { @@ -259,11 +322,6 @@ cal_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *resul priv = E_CAL_SHELL_SIDEBAR (shell_sidebar)->priv; - shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); - shell_content = e_shell_view_get_shell_content (shell_view); - cal_shell_content = E_CAL_SHELL_CONTENT (shell_content); - model = e_cal_shell_content_get_model (cal_shell_content); - if (!e_client_utils_open_new_finish (E_SOURCE (source_object), result, &client, &error)) client = NULL; @@ -271,7 +329,14 @@ cal_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *resul g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED)) { g_error_free (error); goto exit; - } else if (error != NULL) { + } + + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_content = e_shell_view_get_shell_content (shell_view); + cal_shell_content = E_CAL_SHELL_CONTENT (shell_content); + model = e_cal_shell_content_get_model (cal_shell_content); + + if (error != NULL) { e_alert_submit ( E_ALERT_SINK (shell_content), "calendar:failed-open-calendar", @@ -560,6 +625,12 @@ cal_shell_sidebar_dispose (GObject *object) priv->loading_default_client = NULL; } + if (priv->loading_clients != NULL) { + g_cancellable_cancel (priv->loading_clients); + g_object_unref (priv->loading_clients); + priv->loading_clients = NULL; + } + g_hash_table_remove_all (priv->client_table); /* Chain up to parent's dispose() method. */ @@ -864,6 +935,7 @@ cal_shell_sidebar_init (ECalShellSidebar *cal_shell_sidebar) ECalShellSidebarPrivate); cal_shell_sidebar->priv->client_table = client_table; + cal_shell_sidebar->priv->loading_clients = g_cancellable_new (); /* Postpone widget construction until we have a shell view. */ } @@ -1027,7 +1099,7 @@ e_cal_shell_sidebar_add_source (ECalShellSidebar *cal_shell_sidebar, timezone = e_cal_model_get_timezone (model); e_cal_client_set_default_timezone (client, timezone); - e_client_open (E_CLIENT (client), FALSE, NULL, cal_shell_sidebar_client_opened_cb, cal_shell_sidebar); + e_client_open (E_CLIENT (client), FALSE, cal_shell_sidebar->priv->loading_clients, cal_shell_sidebar_client_opened_cb, cal_shell_sidebar); } void diff --git a/modules/calendar/e-memo-shell-sidebar.c b/modules/calendar/e-memo-shell-sidebar.c index 213179cc3a..01806199bb 100644 --- a/modules/calendar/e-memo-shell-sidebar.c +++ b/modules/calendar/e-memo-shell-sidebar.c @@ -55,6 +55,7 @@ struct _EMemoShellSidebarPrivate { ECalClient *default_client; GCancellable *loading_default_client; + GCancellable *loading_clients; }; enum { @@ -176,6 +177,28 @@ memo_shell_sidebar_retrieve_capabilies_cb (GObject *source_object, GAsyncResult memo_shell_sidebar_emit_status_message (memo_shell_sidebar, NULL); } +static gboolean memo_shell_sidebar_retry_open_timeout_cb (gpointer user_data); + +struct RetryOpenData +{ + EClient *client; + EMemoShellSidebar *memo_shell_sidebar; + GCancellable *cancellable; +}; + +static void +free_retry_open_data (gpointer data) +{ + struct RetryOpenData *rod = data; + + if (!rod) + return; + + g_object_unref (rod->client); + g_object_unref (rod->cancellable); + g_free (rod); +} + static void memo_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { @@ -186,22 +209,43 @@ memo_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *resul EShellSidebar *shell_sidebar; GError *error = NULL; - shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar); - shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); - shell_content = e_shell_view_get_shell_content (shell_view); - e_client_open_finish (E_CLIENT (client), result, &error); + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_clear_error (&error); + return; + } + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED) || g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_REQUIRED)) e_client_utils_forget_password (E_CLIENT (client)); if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED)) { - e_client_open (E_CLIENT (client), FALSE, NULL, memo_shell_sidebar_client_opened_cb, user_data); + e_client_open (E_CLIENT (client), FALSE, memo_shell_sidebar->priv->loading_clients, memo_shell_sidebar_client_opened_cb, user_data); + g_clear_error (&error); + return; + } + + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_BUSY)) { + struct RetryOpenData *rod; + + rod = g_new0 (struct RetryOpenData, 1); + rod->client = g_object_ref (client); + rod->memo_shell_sidebar = memo_shell_sidebar; + rod->cancellable = g_object_ref (memo_shell_sidebar->priv->loading_clients); + + /* postpone for 1/2 of a second, backend is busy now */ + g_timeout_add_full (G_PRIORITY_DEFAULT, 500, memo_shell_sidebar_retry_open_timeout_cb, rod, free_retry_open_data); + g_clear_error (&error); return; } + shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_content = e_shell_view_get_shell_content (shell_view); + /* Handle errors. */ switch ((error && error->domain == E_CLIENT_ERROR) ? error->code : -1) { case -1: @@ -240,6 +284,24 @@ memo_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *resul e_client_retrieve_capabilities (E_CLIENT (client), NULL, memo_shell_sidebar_retrieve_capabilies_cb, memo_shell_sidebar); } +static gboolean +memo_shell_sidebar_retry_open_timeout_cb (gpointer user_data) +{ + struct RetryOpenData *rod = user_data; + + g_return_val_if_fail (rod != NULL, FALSE); + g_return_val_if_fail (rod->client != NULL, FALSE); + g_return_val_if_fail (rod->memo_shell_sidebar != NULL, FALSE); + g_return_val_if_fail (rod->cancellable != NULL, FALSE); + + if (g_cancellable_is_cancelled (rod->cancellable)) + return FALSE; + + e_client_open (rod->client, FALSE, rod->memo_shell_sidebar->priv->loading_clients, memo_shell_sidebar_client_opened_cb, rod->memo_shell_sidebar); + + return FALSE; +} + static void memo_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { @@ -254,11 +316,6 @@ memo_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *resu priv = E_MEMO_SHELL_SIDEBAR (shell_sidebar)->priv; - shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); - shell_content = e_shell_view_get_shell_content (shell_view); - memo_shell_content = E_MEMO_SHELL_CONTENT (shell_content); - model = e_memo_shell_content_get_memo_model (memo_shell_content); - if (!e_client_utils_open_new_finish (E_SOURCE (source_object), result, &client, &error)) client = NULL; @@ -266,7 +323,14 @@ memo_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *resu g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED)) { g_error_free (error); goto exit; - } else if (error != NULL) { + } + + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_content = e_shell_view_get_shell_content (shell_view); + memo_shell_content = E_MEMO_SHELL_CONTENT (shell_content); + model = e_memo_shell_content_get_memo_model (memo_shell_content); + + if (error != NULL) { e_alert_submit ( E_ALERT_SINK (shell_content), "calendar:failed-open-memos", @@ -527,6 +591,12 @@ memo_shell_sidebar_dispose (GObject *object) priv->loading_default_client = NULL; } + if (priv->loading_clients != NULL) { + g_cancellable_cancel (priv->loading_clients); + g_object_unref (priv->loading_clients); + priv->loading_clients = NULL; + } + g_hash_table_remove_all (priv->client_table); /* Chain up to parent's dispose() method. */ @@ -760,6 +830,7 @@ memo_shell_sidebar_init (EMemoShellSidebar *memo_shell_sidebar) EMemoShellSidebarPrivate); memo_shell_sidebar->priv->client_table = client_table; + memo_shell_sidebar->priv->loading_clients = g_cancellable_new (); /* Postpone widget construction until we have a shell view. */ } @@ -914,7 +985,7 @@ e_memo_shell_sidebar_add_source (EMemoShellSidebar *memo_shell_sidebar, timezone = e_cal_model_get_timezone (model); e_cal_client_set_default_timezone (client, timezone); - e_client_open (E_CLIENT (client), FALSE, NULL, memo_shell_sidebar_client_opened_cb, memo_shell_sidebar); + e_client_open (E_CLIENT (client), FALSE, memo_shell_sidebar->priv->loading_clients, memo_shell_sidebar_client_opened_cb, memo_shell_sidebar); } void diff --git a/modules/calendar/e-task-shell-sidebar.c b/modules/calendar/e-task-shell-sidebar.c index 04d2c25342..dbb1ba9014 100644 --- a/modules/calendar/e-task-shell-sidebar.c +++ b/modules/calendar/e-task-shell-sidebar.c @@ -55,6 +55,7 @@ struct _ETaskShellSidebarPrivate { ECalClient *default_client; GCancellable *loading_default_client; + GCancellable *loading_clients; }; enum { @@ -176,6 +177,28 @@ task_shell_sidebar_retrieve_capabilies_cb (GObject *source_object, GAsyncResult task_shell_sidebar_emit_status_message (task_shell_sidebar, NULL); } +static gboolean task_shell_sidebar_retry_open_timeout_cb (gpointer user_data); + +struct RetryOpenData +{ + EClient *client; + ETaskShellSidebar *task_shell_sidebar; + GCancellable *cancellable; +}; + +static void +free_retry_open_data (gpointer data) +{ + struct RetryOpenData *rod = data; + + if (!rod) + return; + + g_object_unref (rod->client); + g_object_unref (rod->cancellable); + g_free (rod); +} + static void task_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { @@ -186,22 +209,43 @@ task_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *resul EShellSidebar *shell_sidebar; GError *error = NULL; - shell_sidebar = E_SHELL_SIDEBAR (task_shell_sidebar); - shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); - shell_content = e_shell_view_get_shell_content (shell_view); - e_client_open_finish (E_CLIENT (client), result, &error); + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_clear_error (&error); + return; + } + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED) || g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_REQUIRED)) e_client_utils_forget_password (E_CLIENT (client)); if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED)) { - e_client_open (E_CLIENT (client), FALSE, NULL, task_shell_sidebar_client_opened_cb, user_data); + e_client_open (E_CLIENT (client), FALSE, task_shell_sidebar->priv->loading_clients, task_shell_sidebar_client_opened_cb, user_data); + g_clear_error (&error); + return; + } + + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_BUSY)) { + struct RetryOpenData *rod; + + rod = g_new0 (struct RetryOpenData, 1); + rod->client = g_object_ref (client); + rod->task_shell_sidebar = task_shell_sidebar; + rod->cancellable = g_object_ref (task_shell_sidebar->priv->loading_clients); + + /* postpone for 1/2 of a second, backend is busy now */ + g_timeout_add_full (G_PRIORITY_DEFAULT, 500, task_shell_sidebar_retry_open_timeout_cb, rod, free_retry_open_data); + g_clear_error (&error); return; } + shell_sidebar = E_SHELL_SIDEBAR (task_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_content = e_shell_view_get_shell_content (shell_view); + /* Handle errors. */ switch ((error && error->domain == E_CLIENT_ERROR) ? error->code : -1) { case -1: @@ -240,6 +284,24 @@ task_shell_sidebar_client_opened_cb (GObject *source_object, GAsyncResult *resul e_client_retrieve_capabilities (E_CLIENT (client), NULL, task_shell_sidebar_retrieve_capabilies_cb, task_shell_sidebar); } +static gboolean +task_shell_sidebar_retry_open_timeout_cb (gpointer user_data) +{ + struct RetryOpenData *rod = user_data; + + g_return_val_if_fail (rod != NULL, FALSE); + g_return_val_if_fail (rod->client != NULL, FALSE); + g_return_val_if_fail (rod->task_shell_sidebar != NULL, FALSE); + g_return_val_if_fail (rod->cancellable != NULL, FALSE); + + if (g_cancellable_is_cancelled (rod->cancellable)) + return FALSE; + + e_client_open (rod->client, FALSE, rod->task_shell_sidebar->priv->loading_clients, task_shell_sidebar_client_opened_cb, rod->task_shell_sidebar); + + return FALSE; +} + static void task_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { @@ -254,11 +316,6 @@ task_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *resu priv = E_TASK_SHELL_SIDEBAR (shell_sidebar)->priv; - shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); - shell_content = e_shell_view_get_shell_content (shell_view); - task_shell_content = E_TASK_SHELL_CONTENT (shell_content); - model = e_task_shell_content_get_task_model (task_shell_content); - if (!e_client_utils_open_new_finish (E_SOURCE (source_object), result, &client, &error)) client = NULL; @@ -266,7 +323,14 @@ task_shell_sidebar_default_loaded_cb (GObject *source_object, GAsyncResult *resu g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED)) { g_error_free (error); goto exit; - } else if (error != NULL) { + } + + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_content = e_shell_view_get_shell_content (shell_view); + task_shell_content = E_TASK_SHELL_CONTENT (shell_content); + model = e_task_shell_content_get_task_model (task_shell_content); + + if (error != NULL) { e_alert_submit ( E_ALERT_SINK (shell_content), "calendar:failed-open-tasks", @@ -527,6 +591,12 @@ task_shell_sidebar_dispose (GObject *object) priv->loading_default_client = NULL; } + if (priv->loading_clients != NULL) { + g_cancellable_cancel (priv->loading_clients); + g_object_unref (priv->loading_clients); + priv->loading_clients = NULL; + } + g_hash_table_remove_all (priv->client_table); /* Chain up to parent's dispose() method. */ @@ -760,6 +830,7 @@ task_shell_sidebar_init (ETaskShellSidebar *task_shell_sidebar) ETaskShellSidebarPrivate); task_shell_sidebar->priv->client_table = client_table; + task_shell_sidebar->priv->loading_clients = g_cancellable_new (); /* Postpone widget construction until we have a shell view. */ } @@ -914,7 +985,7 @@ e_task_shell_sidebar_add_source (ETaskShellSidebar *task_shell_sidebar, timezone = e_cal_model_get_timezone (model); e_cal_client_set_default_timezone (client, timezone); - e_client_open (E_CLIENT (client), FALSE, NULL, task_shell_sidebar_client_opened_cb, task_shell_sidebar); + e_client_open (E_CLIENT (client), FALSE, task_shell_sidebar->priv->loading_clients, task_shell_sidebar_client_opened_cb, task_shell_sidebar); } void -- cgit v1.2.3