diff options
author | Milan Crha <mcrha@redhat.com> | 2011-06-27 21:23:31 +0800 |
---|---|---|
committer | Rodrigo Moya <rodrigo@gnome-db.org> | 2011-06-30 00:42:33 +0800 |
commit | 8894b72f2045388990b5696f3e8db97b9544ccf4 (patch) | |
tree | d3ff6f20b45dfc692d5b806f697728b8dd370a25 | |
parent | f286e88fae02a7da640ab1637130b00d3c366c08 (diff) | |
download | gsoc2013-evolution-8894b72f2045388990b5696f3e8db97b9544ccf4.tar gsoc2013-evolution-8894b72f2045388990b5696f3e8db97b9544ccf4.tar.gz gsoc2013-evolution-8894b72f2045388990b5696f3e8db97b9544ccf4.tar.bz2 gsoc2013-evolution-8894b72f2045388990b5696f3e8db97b9544ccf4.tar.lz gsoc2013-evolution-8894b72f2045388990b5696f3e8db97b9544ccf4.tar.xz gsoc2013-evolution-8894b72f2045388990b5696f3e8db97b9544ccf4.tar.zst gsoc2013-evolution-8894b72f2045388990b5696f3e8db97b9544ccf4.zip |
Keep opening EClient-s till they report busy error
-rw-r--r-- | calendar/gui/e-cal-model.c | 72 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 6 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.h | 1 | ||||
-rw-r--r-- | modules/calendar/e-cal-shell-content.c | 1 | ||||
-rw-r--r-- | modules/calendar/e-cal-shell-sidebar.c | 96 | ||||
-rw-r--r-- | modules/calendar/e-memo-shell-sidebar.c | 95 | ||||
-rw-r--r-- | modules/calendar/e-task-shell-sidebar.c | 95 |
7 files changed, 320 insertions, 46 deletions
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c index 9778d3e452..2b4aac732d 100644 --- a/calendar/gui/e-cal-model.c +++ b/calendar/gui/e-cal-model.c @@ -114,6 +114,8 @@ struct _ECalModelPrivate { GSList *notify_removed; GMutex *notify_lock; + + GCancellable *loading_clients; }; static gint ecm_column_count (ETableModel *etm); @@ -377,6 +379,12 @@ cal_model_dispose (GObject *object) priv = E_CAL_MODEL (object)->priv; + if (priv->loading_clients) { + g_cancellable_cancel (priv->loading_clients); + g_object_unref (priv->loading_clients); + priv->loading_clients = NULL; + } + if (priv->clients) { while (priv->clients != NULL) { ECalModelClient *client_data = (ECalModelClient *) priv->clients->data; @@ -701,6 +709,8 @@ e_cal_model_init (ECalModel *model) model->priv->notify_modified = NULL; model->priv->notify_removed = NULL; model->priv->notify_lock = g_mutex_new (); + + model->priv->loading_clients = g_cancellable_new (); } /* ETableModel methods */ @@ -2582,6 +2592,28 @@ cal_model_retrieve_capabilies_cb (GObject *source_object, GAsyncResult *result, update_e_cal_view_for_client (model, client_data); } +struct RetryOpenData +{ + EClient *client; + ECalModel *model; + 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 gboolean cal_model_retry_open_timeout_cb (gpointer user_data); + static void client_opened_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { @@ -2591,6 +2623,28 @@ client_opened_cb (GObject *source_object, GAsyncResult *result, gpointer user_da 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_error_free (error); + return; + } + + if (error && 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->model = model; + rod->cancellable = g_object_ref (model->priv->loading_clients); + + /* postpone for 1/2 of a second, backend is busy now */ + g_timeout_add_full (G_PRIORITY_DEFAULT, 500, cal_model_retry_open_timeout_cb, rod, free_retry_open_data); + + g_error_free (error); + + return; + } + if (error) { e_cal_model_remove_client (model, client); g_debug ("%s: Failed to open '%s': %s", G_STRFUNC, e_client_get_uri (E_CLIENT (client)), error->message); @@ -2600,7 +2654,21 @@ client_opened_cb (GObject *source_object, GAsyncResult *result, gpointer user_da } /* to have them ready for later use */ - e_client_retrieve_capabilities (E_CLIENT (client), NULL, cal_model_retrieve_capabilies_cb, model); + e_client_retrieve_capabilities (E_CLIENT (client), model->priv->loading_clients, cal_model_retrieve_capabilies_cb, model); +} + +static gboolean +cal_model_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->model != NULL, FALSE); + + e_client_open (rod->client, TRUE, rod->cancellable, client_opened_cb, rod->model); + + return FALSE; } static ECalModelClient * @@ -2649,7 +2717,7 @@ add_new_client (ECalModel *model, ECalClient *client, gboolean do_query) e_cal_client_set_default_timezone (client, e_cal_model_get_timezone (model)); - e_client_open (E_CLIENT (client), TRUE, NULL, client_opened_cb, model); + e_client_open (E_CLIENT (client), TRUE, model->priv->loading_clients, client_opened_cb, model); } return client_data; diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 78721bf214..4bb430c018 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -1510,12 +1510,6 @@ gnome_calendar_finalize (GObject *object) G_OBJECT_CLASS (gnome_calendar_parent_class)->finalize (object); } -void -gnome_calendar_dispose (GnomeCalendar *gcal) -{ - g_object_run_dispose (G_OBJECT (gcal)); -} - static void notify_selected_time_changed (GnomeCalendar *gcal) { diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h index 6657b8efe3..58130399f4 100644 --- a/calendar/gui/gnome-cal.h +++ b/calendar/gui/gnome-cal.h @@ -113,7 +113,6 @@ struct _GnomeCalendarClass { GType gnome_calendar_get_type (void); GtkWidget * gnome_calendar_new (void); -void gnome_calendar_dispose (GnomeCalendar *gcal); ECalendar * gnome_calendar_get_date_navigator (GnomeCalendar *gcal); void gnome_calendar_set_date_navigator 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 |