mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-11-11 21:35:35 +01:00
Merge branch 'backport-4820-gdbus-test-race-glib-2-86' into 'glib-2-86'
Backport !4820 “gio/tests: Fix a race condition in /gdbus/connection/flush” to glib-2-86 See merge request GNOME/glib!4821
This commit is contained in:
@@ -28,6 +28,8 @@
|
||||
|
||||
#include "gdbus-tests.h"
|
||||
|
||||
#define WAIT_FOR_FLUSH_MSEC 10000
|
||||
|
||||
/* all tests rely on a shared mainloop */
|
||||
static GMainLoop *loop = NULL;
|
||||
|
||||
@@ -49,7 +51,7 @@ static gboolean
|
||||
test_connection_flush_on_timeout (gpointer user_data)
|
||||
{
|
||||
guint iteration = GPOINTER_TO_UINT (user_data);
|
||||
g_printerr ("Timeout waiting 1000 msec on iteration %d\n", iteration);
|
||||
g_printerr ("Timeout waiting %d msec on iteration %d\n", WAIT_FOR_FLUSH_MSEC, iteration);
|
||||
g_assert_not_reached ();
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -82,6 +84,16 @@ test_connection_flush (void)
|
||||
NULL);
|
||||
g_assert_cmpint (signal_handler_id, !=, 0);
|
||||
|
||||
/* We need to wait for the subscription to have actually taken effect
|
||||
* before forking the subprocess, otherwise there is a race condition
|
||||
* between the message bus adding the match rule and the subprocess
|
||||
* sending the signal. If the message bus wins the race, then the test
|
||||
* passes, but if the subprocess wins the race, it will be too late
|
||||
* for this process to receive the signal because it already happened.
|
||||
* The easiest way to avoid this race is to do a round-trip to the
|
||||
* message bus and back. */
|
||||
connection_wait_for_bus (connection);
|
||||
|
||||
flush_helper = g_test_get_filename (G_TEST_BUILT, "gdbus-connection-flush-helper", NULL);
|
||||
for (n = 0; n < 50; n++)
|
||||
{
|
||||
@@ -108,7 +120,7 @@ test_connection_flush (void)
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (ret);
|
||||
|
||||
timeout_mainloop_id = g_timeout_add (1000, test_connection_flush_on_timeout, GUINT_TO_POINTER (n));
|
||||
timeout_mainloop_id = g_timeout_add (WAIT_FOR_FLUSH_MSEC, test_connection_flush_on_timeout, GUINT_TO_POINTER (n));
|
||||
g_main_loop_run (loop);
|
||||
g_source_remove (timeout_mainloop_id);
|
||||
}
|
||||
|
||||
@@ -620,35 +620,6 @@ typedef struct
|
||||
guint finished_subscription;
|
||||
} Fixture;
|
||||
|
||||
/* Wait for asynchronous messages from @conn to have been processed
|
||||
* by the message bus, as a sequence point so that we can make
|
||||
* "happens before" and "happens after" assertions relative to this.
|
||||
* The easiest way to achieve this is to call a message bus method that has
|
||||
* no arguments and wait for it to return: because the message bus processes
|
||||
* messages in-order, anything we sent before this must have been processed
|
||||
* by the time this call arrives. */
|
||||
static void
|
||||
connection_wait_for_bus (GDBusConnection *conn)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GVariant *call_result;
|
||||
|
||||
call_result = g_dbus_connection_call_sync (conn,
|
||||
DBUS_SERVICE_DBUS,
|
||||
DBUS_PATH_DBUS,
|
||||
DBUS_INTERFACE_DBUS,
|
||||
"GetId",
|
||||
NULL, /* arguments */
|
||||
NULL, /* result type */
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (call_result);
|
||||
g_variant_unref (call_result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when the subscriber receives a message from any connection
|
||||
* announcing that it has emitted all the signals that it plans to emit.
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "gdbus-tests.h"
|
||||
|
||||
#include "gdbusprivate.h"
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct
|
||||
@@ -155,6 +157,40 @@ ensure_gdbus_testserver_up (GDBusConnection *connection,
|
||||
g_main_context_pop_thread_default (context);
|
||||
}
|
||||
|
||||
/*
|
||||
* connection_wait_for_bus:
|
||||
* @conn: A connection
|
||||
*
|
||||
* Wait for asynchronous messages from @conn to have been processed
|
||||
* by the message bus, as a sequence point so that we can make
|
||||
* "happens before" and "happens after" assertions relative to this.
|
||||
* The easiest way to achieve this is to call a message bus method that has
|
||||
* no arguments and wait for it to return: because the message bus processes
|
||||
* messages in-order, anything we sent before this must have been processed
|
||||
* by the time this call arrives.
|
||||
*/
|
||||
void
|
||||
connection_wait_for_bus (GDBusConnection *conn)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GVariant *call_result;
|
||||
|
||||
call_result = g_dbus_connection_call_sync (conn,
|
||||
DBUS_SERVICE_DBUS,
|
||||
DBUS_PATH_DBUS,
|
||||
DBUS_INTERFACE_DBUS,
|
||||
"GetId",
|
||||
NULL, /* arguments */
|
||||
NULL, /* result type */
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (call_result);
|
||||
g_variant_unref (call_result);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct
|
||||
|
||||
@@ -119,6 +119,8 @@ GDBusConnection *_g_bus_get_priv (GBusType bus_type,
|
||||
void ensure_gdbus_testserver_up (GDBusConnection *connection,
|
||||
GMainContext *context);
|
||||
|
||||
void connection_wait_for_bus (GDBusConnection *conn);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __TESTS_H__ */
|
||||
|
||||
Reference in New Issue
Block a user