From: Michael Catanzaro Date: Tue, 26 Sep 2023 23:52:37 +0000 (-0500) Subject: printoperation: fix another case where operation may complete twice X-Git-Tag: archive/raspbian/4.12.4+ds-3+rpi1^2~21^2~1^2~6 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=39560c0914d0fc5ffcb026bff13926c94d05e341;p=gtk4.git printoperation: fix another case where operation may complete twice This is a little tricky. At first, I thought we had a codepath where we fail to schedule the idle that completes the print operation: if we take the gtk_print_backend_printer_list_is_done path for each printer backend, then printer_list_done_cb() is never executed and we never schedule the idle. But in fact, in this case, then backends == NULL at the bottom of find_printer(), and we'll schedule the idle there, so it's OK. Except it's not really OK, because we'll schedule it even if a printer was already found, resulting in the callback completing twice and a double free. Simplify this. Schedule the idle in find_printer() only if there are *initially* no backends, not also if all backends are immediately ready and already removed from consideration. Instead, always call printer_list_done_cb() for every backend in find_printer_init(). After the previous commit, printer_list_done_cb() will schedule the idle when appropriate. printer_list_done_cb() additionally disconnects signals that we did not connect in this codepath, but it does so using g_signal_handlers_disconnect_by_func, which is harmless. Otherwise, the only extra work it's doing is scheduling the idle, and that's exactly what find_printer_init() is missing. --- diff --git a/gtk/print/gtkprintoperation-unix.c b/gtk/print/gtkprintoperation-unix.c index 7a6fb04254..4d592eeb6c 100644 --- a/gtk/print/gtkprintoperation-unix.c +++ b/gtk/print/gtkprintoperation-unix.c @@ -1165,9 +1165,7 @@ find_printer_init (PrinterFinder *finder, if (gtk_print_backend_printer_list_is_done (backend)) { - finder->backends = g_list_remove (finder->backends, backend); - gtk_print_backend_destroy (backend); - g_object_unref (backend); + printer_list_done_cb (backend, finder); } else { @@ -1229,14 +1227,17 @@ find_printer (const char *printer, if (g_module_supported ()) finder->backends = gtk_print_backend_load_modules (); + if (finder->backends == NULL) + { + g_idle_add (find_printer_idle, finder); + return; + } + for (node = finder->backends; !finder->found_printer && node != NULL; node = next) { next = node->next; find_printer_init (finder, GTK_PRINT_BACKEND (node->data)); } - - if (finder->backends == NULL) - g_idle_add (find_printer_idle, finder); }