Blob Blame History Raw
From b8b0347edfb6896b72fd5a207e6cd12d0e578505 Mon Sep 17 00:00:00 2001
From: Felipe Borges <felipeborges@gnome.org>
Date: Thu, 6 Apr 2017 13:11:36 +0200
Subject: [PATCH] printers: Make actualize_printers_list* cancellable

This way we can safely interrupt an update without crashing
g-c-c.

https://bugzilla.gnome.org/show_bug.cgi?id=780299
---
 panels/printers/cc-printers-panel.c | 31 ++++++++++++++++++++++++++++---
 panels/printers/pp-cups.c           |  6 +++++-
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/panels/printers/cc-printers-panel.c b/panels/printers/cc-printers-panel.c
index fb5560843..fb1299982 100644
--- a/panels/printers/cc-printers-panel.c
+++ b/panels/printers/cc-printers-panel.c
@@ -107,6 +107,7 @@ struct _CcPrintersPanelPrivate
   GHashTable   *preferred_drivers;
   GCancellable *get_all_ppds_cancellable;
   GCancellable *subscription_renew_cancellable;
+  GCancellable *actualize_printers_list_cancellable;
 
   gchar    *new_printer_name;
   gchar    *new_printer_location;
@@ -196,6 +197,9 @@ cc_printers_panel_dispose (GObject *object)
   g_cancellable_cancel (priv->subscription_renew_cancellable);
   g_clear_object (&priv->subscription_renew_cancellable);
 
+  g_cancellable_cancel (priv->actualize_printers_list_cancellable);
+  g_clear_object (&priv->actualize_printers_list_cancellable);
+
   detach_from_cups_notifier (CC_PRINTERS_PANEL (object));
 
   if (priv->cups_status_check_id > 0)
@@ -1172,6 +1176,7 @@ actualize_printers_list_cb (GObject      *source_object,
   gboolean                valid = FALSE;
   PpCups                 *cups = PP_CUPS (source_object);
   PpCupsDests            *cups_dests;
+  GError                 *error = NULL;
   gchar                  *current_printer_name = NULL;
   gchar                  *printer_icon_name = NULL;
   gchar                  *default_icon_name = NULL;
@@ -1181,6 +1186,19 @@ actualize_printers_list_cb (GObject      *source_object,
   int                     i, j;
   int                     num_jobs = 0;
 
+  cups_dests = pp_cups_get_dests_finish (cups, result, &error);
+
+  if (cups_dests == NULL && error != NULL)
+    {
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        {
+          g_warning ("Could not get dests: %s", error->message);
+        }
+
+      g_error_free (error);
+      return;
+    }
+
   priv = PRINTERS_PANEL_PRIVATE (self);
 
   treeview = (GtkTreeView*)
@@ -1210,7 +1228,6 @@ actualize_printers_list_cb (GObject      *source_object,
     }
 
   free_dests (self);
-  cups_dests = pp_cups_get_dests_finish (cups, result, NULL);
 
   priv->dests = cups_dests->dests;
   priv->num_dests = cups_dests->num_of_dests;
@@ -1413,10 +1430,16 @@ actualize_printers_list_cb (GObject      *source_object,
 static void
 actualize_printers_list (CcPrintersPanel *self)
 {
-  PpCups *cups;
+  CcPrintersPanelPrivate *priv;
+  PpCups                 *cups;
+
+  priv = PRINTERS_PANEL_PRIVATE (self);
 
   cups = pp_cups_new ();
-  pp_cups_get_dests_async (cups, NULL, actualize_printers_list_cb, self);
+  pp_cups_get_dests_async (cups,
+                           priv->actualize_printers_list_cancellable,
+                           actualize_printers_list_cb,
+                           self);
 }
 
 static void
@@ -3106,6 +3129,8 @@ cc_printers_panel_init (CcPrintersPanel *self)
 
   priv->preferred_drivers = NULL;
 
+  priv->actualize_printers_list_cancellable = g_cancellable_new ();
+
   builder_result = gtk_builder_add_objects_from_resource (priv->builder,
                                                           "/org/gnome/control-center/printers/printers.ui",
                                                           objects, &error);
diff --git a/panels/printers/pp-cups.c b/panels/printers/pp-cups.c
index 6521b90ba..0d0d4a52b 100644
--- a/panels/printers/pp-cups.c
+++ b/panels/printers/pp-cups.c
@@ -73,7 +73,10 @@ _pp_cups_get_dests_thread (GTask        *task,
   dests = g_new0 (PpCupsDests, 1);
   dests->num_of_dests = cupsGetDests (&dests->dests);
 
-  g_task_return_pointer (task, dests, (GDestroyNotify) pp_cups_dests_free);
+  if (g_task_set_return_on_cancel (task, FALSE))
+    {
+      g_task_return_pointer (task, dests, (GDestroyNotify) pp_cups_dests_free);
+    }
 }
 
 void
@@ -85,6 +88,7 @@ pp_cups_get_dests_async (PpCups              *cups,
   GTask       *task;
 
   task = g_task_new (cups, cancellable, callback, user_data);
+  g_task_set_return_on_cancel (task, TRUE);
   g_task_run_in_thread (task, (GTaskThreadFunc) _pp_cups_get_dests_thread);
   g_object_unref (task);
 }
-- 
2.12.2