From afc08836522c84c6d04a81b971d58434711f0666 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 18 May 2022 15:37:19 +0100 Subject: [PATCH] test: Potentially fix a race in thread-pool-slow test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s failed on a CI machine (https://gitlab.gnome.org/GNOME/glib/-/jobs/2006694) with log: ``` [unused] => pushed 100 threads onto the idle pool [unused] stopping unused threads [unused] waiting ONE second for threads to die [unused] waiting ONE second for threads to die [unused] waiting ONE second for threads to die [unused] waiting ONE second for threads to die [unused] waiting ONE second for threads to die [unused] stopped idle threads, 9 remain Bail out! GLib:ERROR:../glib/tests/thread-pool-slow.c:113:test_thread_stop_unused: assertion failed (g_thread_pool_get_num_unused_threads () == 0): (9 == 0) ``` I can’t reproduce this locally, but it’s possible that it failed because a one second wait was not enough to enqueue all the jobs (on a heavily loaded machine), and hence some jobs spawned thread pool threads after calling `g_thread_pool_stop_unused_threads()`, leading to the assertion failure. Signed-off-by: Philip Withnall --- glib/tests/thread-pool-slow.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/glib/tests/thread-pool-slow.c b/glib/tests/thread-pool-slow.c index 7f497418c..cef02db77 100644 --- a/glib/tests/thread-pool-slow.c +++ b/glib/tests/thread-pool-slow.c @@ -61,22 +61,36 @@ test_thread_functions (void) g_assert_cmpint (g_thread_pool_get_max_idle_time (), ==, 0); } +static void +thread_wait_func (gpointer data, + gpointer user_data) +{ + guint timeout_ms = GPOINTER_TO_UINT (data); + guint *n_threads_executed = user_data; + + g_usleep (timeout_ms); + + g_atomic_int_inc (n_threads_executed); +} + static void test_thread_stop_unused (void) { GThreadPool *pool; guint i; guint limit = 100; + guint n_threads_executed = 0; /* Spawn a few threads. */ g_thread_pool_set_max_unused_threads (-1); - pool = g_thread_pool_new ((GFunc) g_usleep, NULL, -1, FALSE, NULL); + pool = g_thread_pool_new (thread_wait_func, &n_threads_executed, -1, FALSE, NULL); for (i = 0; i < limit; i++) g_thread_pool_push (pool, GUINT_TO_POINTER (1000), NULL); /* Wait for the threads to migrate. */ - g_usleep (G_USEC_PER_SEC); + while ((guint) g_atomic_int_get (&n_threads_executed) < limit) + g_usleep (100); g_thread_pool_stop_unused_threads ();