forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
4a7f68e79e
commit
2f3518c80d
@ -1044,6 +1044,7 @@ gtk_main (void)
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
GMainLoop *store_loop;
|
GMainLoop *store_loop;
|
||||||
guint n_clipboards;
|
guint n_clipboards;
|
||||||
|
guint timeout_id;
|
||||||
} ClipboardStore;
|
} ClipboardStore;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1071,13 +1072,20 @@ clipboard_store_finished (GObject *source,
|
|||||||
g_main_loop_quit (store->store_loop);
|
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
|
void
|
||||||
gtk_main_sync (void)
|
gtk_main_sync (void)
|
||||||
{
|
{
|
||||||
ClipboardStore store = { NULL, };
|
ClipboardStore store = { NULL, };
|
||||||
GSList *displays, *l;
|
GSList *displays, *l;
|
||||||
GCancellable *cancel;
|
GCancellable *cancel;
|
||||||
guint store_timeout;
|
|
||||||
|
|
||||||
/* Try storing all clipboard data we have */
|
/* Try storing all clipboard data we have */
|
||||||
displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
|
displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
|
||||||
@ -1101,17 +1109,16 @@ gtk_main_sync (void)
|
|||||||
g_slist_free (displays);
|
g_slist_free (displays);
|
||||||
|
|
||||||
store.store_loop = g_main_loop_new (NULL, TRUE);
|
store.store_loop = g_main_loop_new (NULL, TRUE);
|
||||||
store_timeout = g_timeout_add_seconds (10, (GSourceFunc) g_main_loop_quit, store.store_loop);
|
store.timeout_id = g_timeout_add_seconds (10, (GSourceFunc) sync_timed_out_cb, &store);
|
||||||
g_source_set_name_by_id (store_timeout, "[gtk] gtk_main_sync clipboard store timeout");
|
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))
|
if (g_main_loop_is_running (store.store_loop))
|
||||||
g_main_loop_run (store.store_loop);
|
g_main_loop_run (store.store_loop);
|
||||||
|
|
||||||
g_cancellable_cancel (cancel);
|
g_cancellable_cancel (cancel);
|
||||||
g_object_unref (cancel);
|
g_object_unref (cancel);
|
||||||
g_source_remove (store_timeout);
|
g_clear_handle_id (&store.timeout_id, g_source_remove);
|
||||||
g_main_loop_unref (store.store_loop);
|
g_clear_pointer (&store.store_loop, g_main_loop_unref);
|
||||||
store.store_loop = NULL;
|
|
||||||
|
|
||||||
/* Synchronize the recent manager singleton */
|
/* Synchronize the recent manager singleton */
|
||||||
_gtk_recent_manager_sync ();
|
_gtk_recent_manager_sync ();
|
||||||
|
Loading…
Reference in New Issue
Block a user