From: Christian Hergert Date: Fri, 10 Jan 2020 23:04:44 +0000 (-0800) Subject: gtkmain: be deterministic in source removal X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~20^2~355^2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=2f3518c80dc08aeddfd65273b79d39b325664e3f;p=gtk4.git gtkmain: be deterministic in source removal Fixes gtk_main_sync() to only remove a source if it has not already executed (and been removed). The previous code was using gtk_main_quit() directly which would be non-determinstic based on the previous value in the return register. --- diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 93fea8540a..37ee557c48 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -1044,6 +1044,7 @@ gtk_main (void) typedef struct { GMainLoop *store_loop; guint n_clipboards; + guint timeout_id; } ClipboardStore; static void @@ -1071,13 +1072,20 @@ clipboard_store_finished (GObject *source, g_main_loop_quit (store->store_loop); } +static gboolean +sync_timed_out_cb (ClipboardStore *store) +{ + store->timeout_id = 0; + g_main_loop_quit (store->store_loop); + return G_SOURCE_REMOVE; +} + void gtk_main_sync (void) { ClipboardStore store = { NULL, }; GSList *displays, *l; GCancellable *cancel; - guint store_timeout; /* Try storing all clipboard data we have */ displays = gdk_display_manager_list_displays (gdk_display_manager_get ()); @@ -1101,17 +1109,16 @@ gtk_main_sync (void) g_slist_free (displays); store.store_loop = g_main_loop_new (NULL, TRUE); - store_timeout = g_timeout_add_seconds (10, (GSourceFunc) g_main_loop_quit, store.store_loop); - g_source_set_name_by_id (store_timeout, "[gtk] gtk_main_sync clipboard store timeout"); + store.timeout_id = g_timeout_add_seconds (10, (GSourceFunc) sync_timed_out_cb, &store); + g_source_set_name_by_id (store.timeout_id, "[gtk] gtk_main_sync clipboard store timeout"); if (g_main_loop_is_running (store.store_loop)) g_main_loop_run (store.store_loop); g_cancellable_cancel (cancel); g_object_unref (cancel); - g_source_remove (store_timeout); - g_main_loop_unref (store.store_loop); - store.store_loop = NULL; + g_clear_handle_id (&store.timeout_id, g_source_remove); + g_clear_pointer (&store.store_loop, g_main_loop_unref); /* Synchronize the recent manager singleton */ _gtk_recent_manager_sync ();