mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
tests: Reduce wakeup interval in gdbus-threading
When checking that the connection has the expected number of refs, the test would block on a `GMainContext` iteration for up to 3s before waking up and failing (if the refcount was still not as expected). This check was written in the expectation that changing the refcount of the connection would only happen due to dispatching a source on `GMainContext` — hence the `GMainContext` would wake up as the refcount changed. That’s probably not actually true though. It might be the case that the connection’s refcount is changed on from the GDBus worker thread, which would not cause any wakeups on the main thread’s `GMainContext`. In this case, the `GMainContext` iteration in `assert_connection_has_one_ref()` would block for the full 3s, and then wake up and notice the refcount is correct (then the test would proceed). That’s fine, apart from the fact that `test_threaded_singleton()` does this 1000 times. If the slow case is hit on a significant number of those test runs, the test will take around 3000s to complete, which is significantly more than meson’s test timeout of 360s. So the test fails with something like: ``` 220/266 glib:gio+slow / gdbus-threading TIMEOUT 360.07 s --- command --- G_TEST_SRCDIR='/builds/GNOME/glib/gio/tests' GIO_MODULE_DIR='' G_TEST_BUILDDIR='/builds/GNOME/glib/_build/gio/tests' /builds/GNOME/glib/_build/gio/tests/gdbus-threading --- stdout --- \# random seed: R02S83fe8de22db4d4f376e6d179e2bdd601 1..3 \# Start of gdbus tests ok 1 /gdbus/delivery-in-thread ok 2 /gdbus/method-calls-in-thread \# GLib-GIO-DEBUG: refcount of 0x5602de913660 is not right (3 rather than 1) in test_threaded_singleton(), sleeping \# GLib-GIO-DEBUG: refcount of 0x5602de913660 is not right (3 rather than 1) in test_threaded_singleton(), sleeping \# GLib-GIO-DEBUG: refcount of 0x5602de913c60 is not right (3 rather than 1) in test_threaded_singleton(), sleeping \# GLib-GIO-DEBUG: refcount of 0x5602de913c60 is not right (3 rather than 1) in test_threaded_singleton(), sleeping \# GLib-GIO-DEBUG: refcount of 0x5602de913260 is not right (3 rather than 1) in test_threaded_singleton(), sleeping \# GLib-GIO-DEBUG: refcount of 0x5602de913260 is not right (3 rather than 1) in test_threaded_singleton(), sleeping ``` From this log, it can be seen that the sleep is happening on a different `GMainContext` every other time, so the test *is* making progress. Assuming this is a correct diagnosis (it’s a lot of guessing), this commit tries to fix the test by adding a wakeup timeout to the `GMainContext` in `assert_connection_has_one_ref()`, which will wake it up every 50ms to re-check the exit condition. This polling approach has been taken because it doesn’t seem feasible to make sure that every `g_object_ref()`/`g_object_unref()` call on a `GDBusConnection` causes the main context to wake up. Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This commit is contained in:
parent
fd79c8742b
commit
58f54e8303
@ -44,6 +44,13 @@ timeout_cb (gpointer user_data)
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
wakeup_cb (gpointer user_data)
|
||||
{
|
||||
/* nothing to do here */
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
/* Check that the given @connection has only one ref, waiting to let any pending
|
||||
* unrefs complete first. This is typically used on the shared connection, to
|
||||
* ensure it’s in a correct state before beginning the next test. */
|
||||
@ -53,15 +60,26 @@ static void
|
||||
const gchar *calling_function)
|
||||
{
|
||||
GSource *timeout_source = NULL;
|
||||
GSource *wakeup_source = NULL;
|
||||
TimeoutData data = { context, FALSE };
|
||||
|
||||
if (g_atomic_int_get (&G_OBJECT (connection)->ref_count) == 1)
|
||||
return;
|
||||
|
||||
/* Use two timeout sources: @timeout_source to set a deadline after which the
|
||||
* test will fail if the @connection doesn’t have the right number of refs;
|
||||
* and @wakeup_source to periodically wake the @context up to allow the
|
||||
* termination condition to be checked. This allows the termination condition
|
||||
* to be fulfilled by something which doesn’t wake @context up, such as an
|
||||
* unref happening in the GDBus worker thread. */
|
||||
timeout_source = g_timeout_source_new_seconds (3);
|
||||
g_source_set_callback (timeout_source, timeout_cb, &data, NULL);
|
||||
g_source_attach (timeout_source, context);
|
||||
|
||||
wakeup_source = g_timeout_source_new (50 /* ms */);
|
||||
g_source_set_callback (wakeup_source, wakeup_cb, NULL, NULL);
|
||||
g_source_attach (wakeup_source, context);
|
||||
|
||||
while (g_atomic_int_get (&G_OBJECT (connection)->ref_count) != 1 && !data.timed_out)
|
||||
{
|
||||
g_debug ("refcount of %p is not right (%u rather than 1) in %s(), sleeping",
|
||||
@ -69,6 +87,9 @@ static void
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
}
|
||||
|
||||
g_source_destroy (wakeup_source);
|
||||
g_source_unref (wakeup_source);
|
||||
|
||||
g_source_destroy (timeout_source);
|
||||
g_source_unref (timeout_source);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user