[gnome-control-center] printers: Make the cups connection test cancellable
- From: Felipe Borges <felipeborges src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] printers: Make the cups connection test cancellable
- Date: Fri, 9 Feb 2018 12:32:44 +0000 (UTC)
commit 2ff5cfd6aa412688737dffc4f8699fbe67259507
Author: Felipe Borges <felipeborges gnome org>
Date: Tue Jan 23 18:32:00 2018 +0100
printers: Make the cups connection test cancellable
Currently gnome-control-center could crash whenever a connection
test is interrupted by the disposal of the Printers panel.
Searching in the g-c-c shell for any query that could match the
Printers panel would instantiate the CcPrintersPanel class. Since
we perform a connection test to the printing server as soon as this
object is created, a fast disposal of the panel (by choosing another
search result) would cause the whole application to crash.
https://bugzilla.gnome.org/show_bug.cgi?id=792753
panels/printers/cc-printers-panel.c | 27 +++++++++++++++++++++------
panels/printers/pp-cups.c | 16 +++++++++++-----
panels/printers/pp-cups.h | 4 +++-
3 files changed, 35 insertions(+), 12 deletions(-)
---
diff --git a/panels/printers/cc-printers-panel.c b/panels/printers/cc-printers-panel.c
index e2475737e..f24f29861 100644
--- a/panels/printers/cc-printers-panel.c
+++ b/panels/printers/cc-printers-panel.c
@@ -95,6 +95,7 @@ struct _CcPrintersPanelPrivate
GCancellable *get_all_ppds_cancellable;
GCancellable *subscription_renew_cancellable;
GCancellable *actualize_printers_list_cancellable;
+ GCancellable *cups_status_check_cancellable;
gchar *new_printer_name;
gchar *new_printer_location;
@@ -242,6 +243,9 @@ cc_printers_panel_dispose (GObject *object)
detach_from_cups_notifier (CC_PRINTERS_PANEL (object));
+ g_cancellable_cancel (priv->cups_status_check_cancellable);
+ g_clear_object (&priv->cups_status_check_cancellable);
+
if (priv->cups_status_check_id > 0)
{
g_source_remove (priv->cups_status_check_id);
@@ -809,7 +813,7 @@ set_current_page (GObject *source_object,
priv = PRINTERS_PANEL_PRIVATE (self);
- success = pp_cups_connection_test_finish (cups, result);
+ success = pp_cups_connection_test_finish (cups, result, NULL);
g_object_unref (source_object);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "main-vbox");
@@ -857,7 +861,7 @@ actualize_printers_list_cb (GObject *source_object,
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "main-vbox");
if (priv->num_dests == 0 && !priv->new_printer_name)
- pp_cups_connection_test_async (g_object_ref (cups), set_current_page, self);
+ pp_cups_connection_test_async (g_object_ref (cups), NULL, set_current_page, self);
else
gtk_stack_set_visible_child_name (GTK_STACK (widget), "printers-list");
@@ -1095,7 +1099,7 @@ cups_status_check_cb (GObject *source_object,
priv = self->priv;
- success = pp_cups_connection_test_finish (cups, result);
+ success = pp_cups_connection_test_finish (cups, result, NULL);
if (success)
{
actualize_printers_list (self);
@@ -1118,7 +1122,7 @@ cups_status_check (gpointer user_data)
priv = self->priv;
cups = pp_cups_new ();
- pp_cups_connection_test_async (cups, cups_status_check_cb, self);
+ pp_cups_connection_test_async (cups, NULL, cups_status_check_cb, self);
return priv->cups_status_check_id != 0;
}
@@ -1132,10 +1136,20 @@ connection_test_cb (GObject *source_object,
CcPrintersPanel *self = (CcPrintersPanel*) user_data;
gboolean success;
PpCups *cups = PP_CUPS (source_object);
+ g_autoptr(GError) error = NULL;
priv = self->priv;
- success = pp_cups_connection_test_finish (cups, result);
+ success = pp_cups_connection_test_finish (cups, result, &error);
+
+ if (error != NULL)
+ {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ {
+ g_warning ("Could not test connection: %s", error->message);
+ }
+ }
+
if (!success)
{
priv->cups_status_check_id =
@@ -1264,6 +1278,7 @@ cc_printers_panel_init (CcPrintersPanel *self)
NULL);
priv->actualize_printers_list_cancellable = g_cancellable_new ();
+ priv->cups_status_check_cancellable = g_cancellable_new ();
builder_result = gtk_builder_add_objects_from_resource (priv->builder,
"/org/gnome/control-center/printers/printers.ui",
@@ -1354,7 +1369,7 @@ Please check your installation");
self);
cups = pp_cups_new ();
- pp_cups_connection_test_async (cups, connection_test_cb, self);
+ pp_cups_connection_test_async (cups, priv->cups_status_check_cancellable, connection_test_cb, self);
gtk_container_add (GTK_CONTAINER (self), top_widget);
gtk_widget_show_all (GTK_WIDGET (self));
}
diff --git a/panels/printers/pp-cups.c b/panels/printers/pp-cups.c
index 0d0d4a52b..628d8ae8a 100644
--- a/panels/printers/pp-cups.c
+++ b/panels/printers/pp-cups.c
@@ -112,19 +112,24 @@ connection_test_thread (GTask *task,
http_t *http;
http = httpConnectEncrypt (cupsServer (), ippPort (), cupsEncryption ());
- g_task_return_boolean (task, http != NULL);
-
httpClose (http);
+
+ if (g_task_set_return_on_cancel (task, FALSE))
+ {
+ g_task_return_boolean (task, http != NULL);
+ }
}
void
pp_cups_connection_test_async (PpCups *cups,
+ GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
- task = g_task_new (cups, NULL, callback, user_data);
+ task = g_task_new (cups, cancellable, callback, user_data);
+ g_task_set_return_on_cancel (task, TRUE);
g_task_run_in_thread (task, connection_test_thread);
g_object_unref (task);
@@ -132,11 +137,12 @@ pp_cups_connection_test_async (PpCups *cups,
gboolean
pp_cups_connection_test_finish (PpCups *cups,
- GAsyncResult *result)
+ GAsyncResult *result,
+ GError **error)
{
g_return_val_if_fail (g_task_is_valid (result, cups), FALSE);
- return g_task_propagate_boolean (G_TASK (result), NULL);
+ return g_task_propagate_boolean (G_TASK (result), error);
}
/* Cancels subscription of given id */
diff --git a/panels/printers/pp-cups.h b/panels/printers/pp-cups.h
index 863ca0011..c446febb9 100644
--- a/panels/printers/pp-cups.h
+++ b/panels/printers/pp-cups.h
@@ -66,11 +66,13 @@ PpCupsDests *pp_cups_get_dests_finish (PpCups *cups,
GError **error);
void pp_cups_connection_test_async (PpCups *cups,
+ GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean pp_cups_connection_test_finish (PpCups *cups,
- GAsyncResult *result);
+ GAsyncResult *result,
+ GError **error);
void pp_cups_cancel_subscription_async (PpCups *cups,
gint subscription_id,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]