mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 02:40:11 +00:00
printing: Avoid accessing freed printers
Print backend can be disposed together with all its printers as a reaction to user stopping enumeration of printers. Adding a weak pointer help us to detect that the backend was disposed and hence the backend and its printers should not be used anymore. Fixes #6265
This commit is contained in:
parent
c4dd8d0125
commit
90950b2d3d
@ -3690,6 +3690,19 @@ avahi_request_printer_list (GtkPrintBackendCups *cups_backend)
|
||||
g_bus_get (G_BUS_TYPE_SYSTEM, cups_backend->avahi_cancellable, avahi_create_browsers, cups_backend);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print backend can be disposed together with all its printers
|
||||
* as a reaction to user stopping enumeration of printers.
|
||||
*/
|
||||
static void
|
||||
backend_finalized_cb (gpointer data,
|
||||
GObject *where_the_object_was)
|
||||
{
|
||||
gboolean *backend_finalized = data;
|
||||
|
||||
*backend_finalized = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
|
||||
GtkCupsResult *result,
|
||||
@ -3702,6 +3715,7 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
|
||||
GList *removed_printer_checklist;
|
||||
gchar *remote_default_printer = NULL;
|
||||
GList *iter;
|
||||
gboolean backend_finalized = FALSE;
|
||||
|
||||
gdk_threads_enter ();
|
||||
|
||||
@ -3738,6 +3752,8 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
|
||||
*/
|
||||
removed_printer_checklist = gtk_print_backend_get_printer_list (backend);
|
||||
|
||||
g_object_weak_ref (G_OBJECT (backend), backend_finalized_cb, &backend_finalized);
|
||||
|
||||
response = gtk_cups_result_get_response (result);
|
||||
for (attr = ippFirstAttribute (response); attr != NULL;
|
||||
attr = ippNextAttribute (response))
|
||||
@ -3848,6 +3864,9 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
|
||||
{
|
||||
g_signal_emit_by_name (backend, "printer-added", printer);
|
||||
|
||||
if (backend_finalized)
|
||||
break;
|
||||
|
||||
gtk_printer_set_is_new (printer, FALSE);
|
||||
}
|
||||
|
||||
@ -3884,36 +3903,44 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
|
||||
break;
|
||||
}
|
||||
|
||||
/* look at the removed printers checklist and mark any printer
|
||||
as inactive if it is in the list, emitting a printer_removed signal */
|
||||
if (removed_printer_checklist != NULL)
|
||||
if (!backend_finalized)
|
||||
{
|
||||
for (iter = removed_printer_checklist; iter; iter = iter->next)
|
||||
g_object_weak_unref (G_OBJECT (backend), backend_finalized_cb, &backend_finalized);
|
||||
|
||||
/* look at the removed printers checklist and mark any printer
|
||||
as inactive if it is in the list, emitting a printer_removed signal */
|
||||
if (removed_printer_checklist != NULL)
|
||||
{
|
||||
if (!GTK_PRINTER_CUPS (iter->data)->avahi_browsed)
|
||||
for (iter = removed_printer_checklist; iter; iter = iter->next)
|
||||
{
|
||||
mark_printer_inactive (GTK_PRINTER (iter->data), backend);
|
||||
list_has_changed = TRUE;
|
||||
if (!GTK_PRINTER_CUPS (iter->data)->avahi_browsed)
|
||||
{
|
||||
mark_printer_inactive (GTK_PRINTER (iter->data), backend);
|
||||
list_has_changed = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (removed_printer_checklist);
|
||||
}
|
||||
|
||||
g_list_free (removed_printer_checklist);
|
||||
|
||||
done:
|
||||
if (list_has_changed)
|
||||
g_signal_emit_by_name (backend, "printer-list-changed");
|
||||
|
||||
gtk_print_backend_set_list_done (backend);
|
||||
|
||||
if (!cups_backend->got_default_printer && remote_default_printer != NULL)
|
||||
if (!backend_finalized)
|
||||
{
|
||||
set_default_printer (cups_backend, remote_default_printer);
|
||||
g_free (remote_default_printer);
|
||||
}
|
||||
if (list_has_changed)
|
||||
g_signal_emit_by_name (backend, "printer-list-changed");
|
||||
|
||||
if (!cups_backend->got_default_printer && cups_backend->avahi_default_printer != NULL)
|
||||
set_default_printer (cups_backend, cups_backend->avahi_default_printer);
|
||||
gtk_print_backend_set_list_done (backend);
|
||||
|
||||
if (!cups_backend->got_default_printer && remote_default_printer != NULL)
|
||||
{
|
||||
set_default_printer (cups_backend, remote_default_printer);
|
||||
g_free (remote_default_printer);
|
||||
}
|
||||
|
||||
if (!cups_backend->got_default_printer && cups_backend->avahi_default_printer != NULL)
|
||||
set_default_printer (cups_backend, cups_backend->avahi_default_printer);
|
||||
}
|
||||
|
||||
gdk_threads_leave ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user