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 *get_all_ppds_cancellable;
|
||||||
GCancellable *subscription_renew_cancellable;
|
GCancellable *subscription_renew_cancellable;
|
||||||
GCancellable *actualize_printers_list_cancellable;
|
GCancellable *actualize_printers_list_cancellable;
|
||||||
|
GCancellable *cups_status_check_cancellable;
|
||||||
|
|
||||||
gchar *new_printer_name;
|
gchar *new_printer_name;
|
||||||
gchar *new_printer_location;
|
gchar *new_printer_location;
|
||||||
|
@ -242,6 +243,9 @@ cc_printers_panel_dispose (GObject *object)
|
||||||
|
|
||||||
detach_from_cups_notifier (CC_PRINTERS_PANEL (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)
|
if (priv->cups_status_check_id > 0)
|
||||||
{
|
{
|
||||||
g_source_remove (priv->cups_status_check_id);
|
g_source_remove (priv->cups_status_check_id);
|
||||||
|
@ -809,7 +813,7 @@ set_current_page (GObject *source_object,
|
||||||
|
|
||||||
priv = PRINTERS_PANEL_PRIVATE (self);
|
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);
|
g_object_unref (source_object);
|
||||||
|
|
||||||
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "main-vbox");
|
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");
|
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "main-vbox");
|
||||||
if (priv->num_dests == 0 && !priv->new_printer_name)
|
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
|
else
|
||||||
gtk_stack_set_visible_child_name (GTK_STACK (widget), "printers-list");
|
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;
|
priv = self->priv;
|
||||||
|
|
||||||
success = pp_cups_connection_test_finish (cups, result);
|
success = pp_cups_connection_test_finish (cups, result, NULL);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
actualize_printers_list (self);
|
actualize_printers_list (self);
|
||||||
|
@ -1118,7 +1122,7 @@ cups_status_check (gpointer user_data)
|
||||||
priv = self->priv;
|
priv = self->priv;
|
||||||
|
|
||||||
cups = pp_cups_new ();
|
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;
|
return priv->cups_status_check_id != 0;
|
||||||
}
|
}
|
||||||
|
@ -1132,10 +1136,20 @@ connection_test_cb (GObject *source_object,
|
||||||
CcPrintersPanel *self = (CcPrintersPanel*) user_data;
|
CcPrintersPanel *self = (CcPrintersPanel*) user_data;
|
||||||
gboolean success;
|
gboolean success;
|
||||||
PpCups *cups = PP_CUPS (source_object);
|
PpCups *cups = PP_CUPS (source_object);
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
priv = self->priv;
|
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)
|
if (!success)
|
||||||
{
|
{
|
||||||
priv->cups_status_check_id =
|
priv->cups_status_check_id =
|
||||||
|
@ -1264,6 +1278,7 @@ cc_printers_panel_init (CcPrintersPanel *self)
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
priv->actualize_printers_list_cancellable = g_cancellable_new ();
|
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,
|
builder_result = gtk_builder_add_objects_from_resource (priv->builder,
|
||||||
"/org/gnome/control-center/printers/printers.ui",
|
"/org/gnome/control-center/printers/printers.ui",
|
||||||
|
@ -1354,7 +1369,7 @@ Please check your installation");
|
||||||
self);
|
self);
|
||||||
|
|
||||||
cups = pp_cups_new ();
|
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_container_add (GTK_CONTAINER (self), top_widget);
|
||||||
gtk_widget_show_all (GTK_WIDGET (self));
|
gtk_widget_show_all (GTK_WIDGET (self));
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,19 +112,24 @@ connection_test_thread (GTask *task,
|
||||||
http_t *http;
|
http_t *http;
|
||||||
|
|
||||||
http = httpConnectEncrypt (cupsServer (), ippPort (), cupsEncryption ());
|
http = httpConnectEncrypt (cupsServer (), ippPort (), cupsEncryption ());
|
||||||
g_task_return_boolean (task, http != NULL);
|
|
||||||
|
|
||||||
httpClose (http);
|
httpClose (http);
|
||||||
|
|
||||||
|
if (g_task_set_return_on_cancel (task, FALSE))
|
||||||
|
{
|
||||||
|
g_task_return_boolean (task, http != NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pp_cups_connection_test_async (PpCups *cups,
|
pp_cups_connection_test_async (PpCups *cups,
|
||||||
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GTask *task;
|
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_task_run_in_thread (task, connection_test_thread);
|
||||||
|
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
|
@ -132,11 +137,12 @@ pp_cups_connection_test_async (PpCups *cups,
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
pp_cups_connection_test_finish (PpCups *cups,
|
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);
|
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 */
|
/* Cancels subscription of given id */
|
||||||
|
|
|
@ -66,11 +66,13 @@ PpCupsDests *pp_cups_get_dests_finish (PpCups *cups,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
void pp_cups_connection_test_async (PpCups *cups,
|
void pp_cups_connection_test_async (PpCups *cups,
|
||||||
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
gboolean pp_cups_connection_test_finish (PpCups *cups,
|
gboolean pp_cups_connection_test_finish (PpCups *cups,
|
||||||
GAsyncResult *result);
|
GAsyncResult *result,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
void pp_cups_cancel_subscription_async (PpCups *cups,
|
void pp_cups_cancel_subscription_async (PpCups *cups,
|
||||||
gint subscription_id,
|
gint subscription_id,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue