[gnome-control-center/gnome-3-8] printers: Don't crash after changing an option



commit b29cebede0d3d108e07db582a71902e7d0dbe411
Author: Marek Kasik <mkasik redhat com>
Date:   Thu Feb 28 16:19:21 2013 +0100

    printers: Don't crash after changing an option
    
    Use GCancellable when setting a new value of an option.
    This prevents Printers panel from crash caused by
    calling of option widget's callback on finalized widget.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=694874

 panels/printers/pp-ipp-option-widget.c |   39 +++++++++++++++++++++++++++++--
 panels/printers/pp-ppd-option-widget.c |   30 +++++++++++++++++++++++-
 panels/printers/pp-utils.c             |    6 +++-
 3 files changed, 68 insertions(+), 7 deletions(-)
---
diff --git a/panels/printers/pp-ipp-option-widget.c b/panels/printers/pp-ipp-option-widget.c
index 0fa5410..70acaa8 100644
--- a/panels/printers/pp-ipp-option-widget.c
+++ b/panels/printers/pp-ipp-option-widget.c
@@ -52,6 +52,8 @@ struct PpIPPOptionWidgetPrivate
   gchar *option_name;
 
   GHashTable *ipp_attribute;
+
+  GCancellable *cancellable;
 };
 
 G_DEFINE_TYPE (PpIPPOptionWidget, pp_ipp_option_widget, GTK_TYPE_HBOX)
@@ -163,6 +165,12 @@ pp_ipp_option_widget_finalize (GObject *object)
           g_hash_table_unref (priv->ipp_attribute);
           priv->ipp_attribute = NULL;
         }
+
+      if (priv->cancellable)
+        {
+          g_cancellable_cancel (priv->cancellable);
+          g_object_unref (priv->cancellable);
+        }
     }
 
   G_OBJECT_CLASS (pp_ipp_option_widget_parent_class)->finalize (object);
@@ -308,7 +316,11 @@ static void
 printer_add_option_async_cb (gboolean success,
                              gpointer user_data)
 {
+  PpIPPOptionWidget        *widget = (PpIPPOptionWidget *) user_data;
+  PpIPPOptionWidgetPrivate *priv = widget->priv;
+
   update_widget (user_data);
+  g_clear_object (&priv->cancellable);
 }
 
 static void
@@ -326,11 +338,18 @@ switch_changed_cb (GtkWidget         *switch_button,
   else
     values[0] = g_strdup ("False");
 
+  if (priv->cancellable)
+    {
+      g_cancellable_cancel (priv->cancellable);
+      g_object_unref (priv->cancellable);
+    }
+
+  priv->cancellable = g_cancellable_new ();
   printer_add_option_async (priv->printer_name,
                             priv->option_name,
                             values,
                             TRUE,
-                            NULL,
+                            priv->cancellable,
                             printer_add_option_async_cb,
                             widget);
 
@@ -347,11 +366,18 @@ combo_changed_cb (GtkWidget         *combo,
   values = g_new0 (gchar *, 2);
   values[0] = combo_box_get (combo);
 
+  if (priv->cancellable)
+    {
+      g_cancellable_cancel (priv->cancellable);
+      g_object_unref (priv->cancellable);
+    }
+
+  priv->cancellable = g_cancellable_new ();
   printer_add_option_async (priv->printer_name,
                             priv->option_name,
                             values,
                             TRUE,
-                            NULL,
+                            priv->cancellable,
                             printer_add_option_async_cb,
                             widget);
 
@@ -368,11 +394,18 @@ spin_button_changed_cb (GtkWidget         *spin_button,
   values = g_new0 (gchar *, 2);
   values[0] = g_strdup_printf ("%d", gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin_button)));
 
+  if (priv->cancellable)
+    {
+      g_cancellable_cancel (priv->cancellable);
+      g_object_unref (priv->cancellable);
+    }
+
+  priv->cancellable = g_cancellable_new ();
   printer_add_option_async (priv->printer_name,
                             priv->option_name,
                             values,
                             TRUE,
-                            NULL,
+                            priv->cancellable,
                             printer_add_option_async_cb,
                             widget);
 
diff --git a/panels/printers/pp-ppd-option-widget.c b/panels/printers/pp-ppd-option-widget.c
index 4bd9e12..13f3674 100644
--- a/panels/printers/pp-ppd-option-widget.c
+++ b/panels/printers/pp-ppd-option-widget.c
@@ -56,6 +56,8 @@ struct PpPPDOptionWidgetPrivate
 
   gchar    *ppd_filename;
   gboolean  ppd_filename_set;
+
+  GCancellable *cancellable;
 };
 
 G_DEFINE_TYPE (PpPPDOptionWidget, pp_ppd_option_widget, GTK_TYPE_HBOX)
@@ -203,6 +205,12 @@ pp_ppd_option_widget_finalize (GObject *object)
           g_free (priv->ppd_filename);
           priv->ppd_filename = NULL;
         }
+
+      if (priv->cancellable)
+        {
+          g_cancellable_cancel (priv->cancellable);
+          g_object_unref (priv->cancellable);
+        }
     }
 
   G_OBJECT_CLASS (pp_ppd_option_widget_parent_class)->finalize (object);
@@ -361,7 +369,11 @@ static void
 printer_add_option_async_cb (gboolean success,
                              gpointer user_data)
 {
+  PpPPDOptionWidget        *widget = (PpPPDOptionWidget *) user_data;
+  PpPPDOptionWidgetPrivate *priv = widget->priv;
+
   update_widget (user_data);
+  g_clear_object (&priv->cancellable);
 }
 
 static void
@@ -379,11 +391,18 @@ switch_changed_cb (GtkWidget         *switch_button,
   else
     values[0] = g_strdup ("False");
 
+  if (priv->cancellable)
+    {
+      g_cancellable_cancel (priv->cancellable);
+      g_object_unref (priv->cancellable);
+    }
+
+  priv->cancellable = g_cancellable_new ();
   printer_add_option_async (priv->printer_name,
                             priv->option_name,
                             values,
                             FALSE,
-                            NULL,
+                            priv->cancellable,
                             printer_add_option_async_cb,
                             widget);
 
@@ -400,11 +419,18 @@ combo_changed_cb (GtkWidget         *combo,
   values = g_new0 (gchar *, 2);
   values[0] = combo_box_get (combo);
 
+  if (priv->cancellable)
+    {
+      g_cancellable_cancel (priv->cancellable);
+      g_object_unref (priv->cancellable);
+    }
+
+  priv->cancellable = g_cancellable_new ();
   printer_add_option_async (priv->printer_name,
                             priv->option_name,
                             values,
                             FALSE,
-                            NULL,
+                            priv->cancellable,
                             printer_add_option_async_cb,
                             widget);
 
diff --git a/panels/printers/pp-utils.c b/panels/printers/pp-utils.c
index 54cbeda..9ec6c73 100644
--- a/panels/printers/pp-utils.c
+++ b/panels/printers/pp-utils.c
@@ -3347,7 +3347,8 @@ printer_add_option_async_dbus_cb (GObject      *source_object,
       g_error_free (error);
     }
 
-  data->callback (success, data->user_data);
+  if (!g_cancellable_is_cancelled (data->cancellable))
+    data->callback (success, data->user_data);
 
   if (data->cancellable)
     g_object_unref (data->cancellable);
@@ -3386,7 +3387,8 @@ printer_add_option_async (const gchar   *printer_name,
     }
 
   data = g_new0 (PAOData, 1);
-  data->cancellable = cancellable;
+  if (cancellable)
+    data->cancellable = g_object_ref (cancellable);
   data->callback = callback;
   data->user_data = user_data;
 


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