From 76f689195e0e753bee34a139dc07ab262e0bf199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Wed, 12 Jun 2024 22:47:37 +0200 Subject: [PATCH] tests/utils: Actually block while waiting for input thread flushing meta_flush_input() creates and runs a main loop in order to block until the input thread has flushed all its events. This main loop is created on the default main context though (NULL is passed to g_main_loop_new()), which means that while the main loop runs, the default main context is active (aka stage updates will happen). This causes an issue with tests, specifically when there already is a stage update queued before running meta_flush_input(): meta_flush_input() will (as expected) block until the input thread flushed all its events to the main thread. But while that is happening, the main thread will be doing the stage update that was already queued, without the new events (the input thread is just starting to flush those). Then meta_flush_input() returns, and in our test we see that the stage has been updated, except it wasn't updated with the latest events. The test now continues and fails. To fix the issue, make meta_flush_input() truly blocking, so that it only flushes the input thread, but doesn't drive the global main context while waiting for that. After the flushing is finished, tests must now manually iterate the main context themselves to ensure that a stage update happens. This breaks a few stacking tests, because "move_cursor_to" and "click" use meta_flush_input() internally. For those commands we now need to dispatch a stage update afterwards. Part-of: --- src/tests/meta-test-utils.c | 23 ++++++++++------------- src/tests/test-runner.c | 2 ++ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/tests/meta-test-utils.c b/src/tests/meta-test-utils.c index 1f2184abb..3de6a0475 100644 --- a/src/tests/meta-test-utils.c +++ b/src/tests/meta-test-utils.c @@ -877,19 +877,16 @@ meta_create_test_monitor (MetaContext *context, } #ifdef HAVE_NATIVE_BACKEND -static gboolean -callback_idle (gpointer user_data) -{ - GMainLoop *loop = user_data; - - g_main_loop_quit (loop); - return G_SOURCE_REMOVE; -} +static GMutex mutex; +static GCond cond; static gboolean queue_callback (GTask *task) { - g_idle_add (callback_idle, g_task_get_task_data (task)); + g_mutex_lock (&mutex); + g_cond_signal (&cond); + g_mutex_unlock (&mutex); + return G_SOURCE_REMOVE; } #endif @@ -902,7 +899,6 @@ meta_flush_input (MetaContext *context) ClutterSeat *seat; MetaSeatNative *seat_native; g_autoptr (GTask) task = NULL; - g_autoptr (GMainLoop) loop = NULL; g_assert_true (META_IS_BACKEND_NATIVE (backend)); @@ -910,12 +906,13 @@ meta_flush_input (MetaContext *context) seat_native = META_SEAT_NATIVE (seat); task = g_task_new (backend, NULL, NULL, NULL); - loop = g_main_loop_new (NULL, FALSE); - g_task_set_task_data (task, loop, NULL); + + g_mutex_lock (&mutex); meta_seat_impl_run_input_task (seat_native->impl, task, (GSourceFunc) queue_callback); - g_main_loop_run (loop); + g_cond_wait (&cond, &mutex); + g_mutex_unlock (&mutex); #endif } diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c index 6cce5909b..b85880952 100644 --- a/src/tests/test-runner.c +++ b/src/tests/test-runner.c @@ -1714,6 +1714,8 @@ test_case_do (TestCase *test, CLUTTER_CURRENT_TIME, x, y); meta_flush_input (test->context); + if (!test_case_dispatch (test, error)) + return FALSE; } else if (strcmp (argv[0], "click") == 0) {