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
This commit is contained in:
parent
24d1e7f7d2
commit
2ff5cfd6aa
3 changed files with 35 additions and 12 deletions
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue