1
0
Fork 0

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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3807>
This commit is contained in:
Jonas Dreßler 2024-06-12 22:47:37 +02:00 committed by Marge Bot
parent 23a4261736
commit 76f689195e
2 changed files with 12 additions and 13 deletions

View file

@ -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
}

View file

@ -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)
{