printoperation: add some assertions
authorMichael Catanzaro <mcatanzaro@redhat.com>
Wed, 27 Sep 2023 00:25:41 +0000 (19:25 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Thu, 28 Sep 2023 00:42:45 +0000 (20:42 -0400)
Let's assert that we schedule the idle callback exactly once.

These assertions are not perfect because if the callback executes before
we schedule it, then the assertion itself would be a use-after-free,
since I'm using the PrinterFinder to track whether the callback that
frees it has been scheduled. But in practice when using loupe's print
dialog, I was noticing the callback scheduled twice before it was
executed. The assertion would have caught this problem.

gtk/print/gtkprintoperation-unix.c

index 4d592eeb6cddeb07064dae1d72f3180a95772511..ab69e1970be0aaa53cf207a8d6a6eed2c68187f5 100644 (file)
@@ -1056,6 +1056,7 @@ gtk_print_run_page_setup_dialog_async (GtkWindow            *parent,
 struct _PrinterFinder
 {
   gboolean found_printer;
+  gboolean scheduled_callback;
   GFunc func;
   gpointer data;
   char *printer_name;
@@ -1088,6 +1089,14 @@ find_printer_idle (gpointer data)
   return G_SOURCE_REMOVE;
 }
 
+static void
+schedule_finder_callback (PrinterFinder *finder)
+{
+  g_assert (!finder->scheduled_callback);
+  g_idle_add (find_printer_idle, finder);
+  finder->scheduled_callback = TRUE;
+}
+
 static void
 printer_added_cb (GtkPrintBackend *backend,
                   GtkPrinter      *printer,
@@ -1120,7 +1129,7 @@ printer_added_cb (GtkPrintBackend *backend,
     }
 
   if (finder->found_printer)
-    g_idle_add (find_printer_idle, finder);
+    schedule_finder_callback (finder);
 }
 
 static void
@@ -1139,7 +1148,7 @@ printer_list_done_cb (GtkPrintBackend *backend,
    * above, then we're finished.
    */
   if (finder->backends == NULL && !finder->found_printer)
-    g_idle_add (find_printer_idle, finder);
+    schedule_finder_callback (finder);
 }
 
 static void
@@ -1229,7 +1238,7 @@ find_printer (const char *printer,
 
   if (finder->backends == NULL)
     {
-      g_idle_add (find_printer_idle, finder);
+      schedule_finder_callback (finder);
       return;
     }