[gtk+] app-chooser-dialog: make sure to hold a ref when doing async ops



commit 623b5192cc5d466cee5ed5e9bbb7f343df7dbba8
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Feb 1 13:16:06 2012 -0500

    app-chooser-dialog: make sure to hold a ref when doing async ops
    
    Hold a ref to the GtkDialog while doing async operations with the
    GtkAppChooserOnline object.
    This is needed, since somebody could call gtk_widget_destroy() on us
    while an async operation is in progress. We don't want to be finalized
    in that case, but mark the fact that we were dismissed and just return
    from the callback in that case.
    This avoids crashing if the dialog is destroyed in the middle of a PK
    operation.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=649121

 gtk/gtkappchooserdialog.c |   19 ++++++++++++++++---
 1 files changed, 16 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtkappchooserdialog.c b/gtk/gtkappchooserdialog.c
index 8d03cc0..c0ee59c 100644
--- a/gtk/gtkappchooserdialog.c
+++ b/gtk/gtkappchooserdialog.c
@@ -80,6 +80,7 @@ struct _GtkAppChooserDialogPrivate {
   GCancellable *online_cancellable;
 
   gboolean show_more_clicked;
+  gboolean dismissed;
 };
 
 enum {
@@ -129,6 +130,9 @@ search_for_mimetype_ready_cb (GObject      *source,
 
   _gtk_app_chooser_online_search_for_mimetype_finish (online, res, &error);
 
+  if (self->priv->dismissed)
+    goto out;
+
   if (error != NULL &&
       !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
     {
@@ -141,7 +145,9 @@ search_for_mimetype_ready_cb (GObject      *source,
       gtk_app_chooser_refresh (GTK_APP_CHOOSER (self->priv->app_chooser_widget));
     }
 
+ out:
   g_clear_error (&error);
+  g_object_unref (self);
 
   gdk_threads_leave ();
 }
@@ -160,7 +166,7 @@ online_button_clicked_cb (GtkButton *b,
 						     GTK_WINDOW (self),
                                                      self->priv->online_cancellable,
 						     search_for_mimetype_ready_cb,
-						     self);
+						     g_object_ref (self));
 }
 
 static void
@@ -174,7 +180,8 @@ app_chooser_online_get_default_ready_cb (GObject *source,
 
   self->priv->online = _gtk_app_chooser_online_get_default_finish (source, res);
 
-  if (self->priv->online != NULL)
+  if (self->priv->online != NULL &&
+      !self->priv->dismissed)
     {
       GtkWidget *action_area;
 
@@ -194,13 +201,16 @@ app_chooser_online_get_default_ready_cb (GObject *source,
       gtk_widget_show (self->priv->online_button);
     }
 
+  g_object_unref (self);
+
   gdk_threads_leave ();
 }
 
 static void
 ensure_online_button (GtkAppChooserDialog *self)
 {
-  _gtk_app_chooser_online_get_default_async (app_chooser_online_get_default_ready_cb, self);
+  _gtk_app_chooser_online_get_default_async (app_chooser_online_get_default_ready_cb,
+                                             g_object_ref (self));
 }
 
 /* An application is valid if:
@@ -298,6 +308,9 @@ gtk_app_chooser_dialog_response (GtkDialog *dialog,
     case GTK_RESPONSE_OK:
       add_or_find_application (self);
       break;
+    case GTK_RESPONSE_CANCEL:
+    case GTK_RESPONSE_DELETE_EVENT:
+      self->priv->dismissed = TRUE;
     default :
       break;
     }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]