[gnome-online-accounts] telepathy: Fix a race between TpawAccountWidget and GoaTpAccountLinker



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]