[gnome-online-accounts] telepathy: Fix a race between TpawAccountWidget and GoaTpAccountLinker
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts] telepathy: Fix a race between TpawAccountWidget and GoaTpAccountLinker
- Date: Tue, 7 Jun 2016 15:46:56 +0000 (UTC)
commit c4fa9441fde8999febc2347b46f43591cff5d62d
Author: Debarshi Ray <debarshir gnome org>
Date: Fri Jun 3 20:56:36 2016 +0200
telepathy: Fix a race between TpawAccountWidget and GoaTpAccountLinker
If TpawAccountWidget is used with a GtkDialog, the job completion
semantics are as follows:
GtkDialog::response is emitted when the user clicks the Add button.
However, at this point the operation has just begun - the TpAccount
hasn't even been created. Once it is ready, TpawAccountWidget::close
(and a second GtkDialog::response) will be emitted.
Apart from this, we need to track whether the corresponding GoaObject
has been created by GoaTpAccountLinker.
We were quitting our hand rolled GMainLoop immediately after the
TpAccount / GoaObject pair were created without having anything to
wait for the TpawAccountWidget::close emission. This is wrong because
TpawAccountWidget does some follow-up work on the TpAccount after its
creation. Therefore, we were terminating add_account while some
asynchronous TpawAccountWidget operations could still be running.
(Even though TpawAccountWidget holds a reference to itself during an
asynchronous operation, the destruction of the GtkDialog leads to
the widget being disposed.)
Therefore, we track both the TpawAccountWidget::close emission and the
GoaObject creation. We quit the GMainLoop only after both events have
occured.
https://bugzilla.gnome.org/show_bug.cgi?id=767299
src/goabackend/goatelepathyprovider.c | 27 ++++++++++++++++++++-------
1 files changed, 20 insertions(+), 7 deletions(-)
---
diff --git a/src/goabackend/goatelepathyprovider.c b/src/goabackend/goatelepathyprovider.c
index a5f0c97..a285213 100644
--- a/src/goabackend/goatelepathyprovider.c
+++ b/src/goabackend/goatelepathyprovider.c
@@ -276,6 +276,7 @@ typedef struct
GoaTelepathyProvider *provider;
GtkDialog *dialog;
GtkBox *vbox;
+ gboolean close_received;
TpAccount *tp_account;
@@ -283,6 +284,20 @@ typedef struct
guint goa_account_added_id;
} AddAccountData;
+static void
+quit_main_loop_if_finished (AddAccountData *data)
+{
+ if (data->ret != NULL && data->close_received)
+ g_main_loop_quit (data->loop);
+}
+
+static void
+run_main_loop_if_needed (AddAccountData *data)
+{
+ if (data->ret == NULL || !data->close_received)
+ g_main_loop_run (data->loop);
+}
+
static gboolean
check_goa_object_match (AddAccountData *data,
GoaObject *goa_object)
@@ -312,7 +327,7 @@ check_goa_object_match (AddAccountData *data,
{
/* Found it! */
data->ret = g_object_ref (goa_object);
- g_main_loop_quit (data->loop);
+ quit_main_loop_if_finished (data);
return TRUE;
}
@@ -369,7 +384,8 @@ account_widget_close_cb (TpawAccountWidget *widget,
GtkResponseType response,
AddAccountData *data)
{
- gtk_dialog_response (data->dialog, response);
+ data->close_received = TRUE;
+ quit_main_loop_if_finished (data);
}
static GoaObject *
@@ -443,11 +459,8 @@ add_account (GoaProvider *provider,
goto out;
}
- if (data.ret == NULL)
- {
- /* We wait for the account to be created */
- g_main_loop_run (data.loop);
- }
+ /* We wait for the account to be created */
+ run_main_loop_if_needed (&data);
out:
if (data.error != NULL)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]