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
This commit is contained in:
Marek Kasik 2013-02-28 16:19:21 +01:00
parent affe13b180
commit 76d18ec85d
3 changed files with 68 additions and 7 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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;