mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-27 22:46:15 +01:00
Merge branch 'wip/pwithnall/2092-stupid-dbus-tests-again' into 'master'
tests: Fix remaining race in gdbus-connection filter test Closes #1957 and #2092 See merge request GNOME/glib!1476
This commit is contained in:
commit
da84e9eb26
@ -817,9 +817,8 @@ test_connection_signal_match_rules (void)
|
|||||||
* so all accesses must be atomic. */
|
* so all accesses must be atomic. */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
guint num_handled; /* (atomic) */
|
GAsyncQueue *incoming_queue; /* (element-type GDBusMessage) */
|
||||||
guint num_outgoing; /* (atomic) */
|
guint num_outgoing; /* (atomic) */
|
||||||
guint32 serial; /* (atomic) */
|
|
||||||
} FilterData;
|
} FilterData;
|
||||||
|
|
||||||
/* Runs in a worker thread. */
|
/* Runs in a worker thread. */
|
||||||
@ -830,22 +829,31 @@ filter_func (GDBusConnection *connection,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
FilterData *data = user_data;
|
FilterData *data = user_data;
|
||||||
guint32 reply_serial;
|
|
||||||
|
|
||||||
if (incoming)
|
if (incoming)
|
||||||
{
|
g_async_queue_push (data->incoming_queue, g_object_ref (message));
|
||||||
reply_serial = g_dbus_message_get_reply_serial (message);
|
|
||||||
if (reply_serial == g_atomic_int_get (&data->serial))
|
|
||||||
g_atomic_int_inc (&data->num_handled);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
g_atomic_int_inc (&data->num_outgoing);
|
||||||
g_atomic_int_inc (&data->num_outgoing);
|
|
||||||
}
|
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wait_for_filtered_reply (GAsyncQueue *incoming_queue,
|
||||||
|
guint32 expected_serial)
|
||||||
|
{
|
||||||
|
GDBusMessage *popped_message = NULL;
|
||||||
|
|
||||||
|
while ((popped_message = g_async_queue_pop (incoming_queue)) != NULL)
|
||||||
|
{
|
||||||
|
guint32 reply_serial = g_dbus_message_get_reply_serial (popped_message);
|
||||||
|
g_object_unref (popped_message);
|
||||||
|
if (reply_serial == expected_serial)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -933,7 +941,7 @@ static void
|
|||||||
test_connection_filter (void)
|
test_connection_filter (void)
|
||||||
{
|
{
|
||||||
GDBusConnection *c;
|
GDBusConnection *c;
|
||||||
FilterData data = { 0, 0, 0 };
|
FilterData data = { NULL, 0 };
|
||||||
GDBusMessage *m;
|
GDBusMessage *m;
|
||||||
GDBusMessage *m2;
|
GDBusMessage *m2;
|
||||||
GDBusMessage *r;
|
GDBusMessage *r;
|
||||||
@ -953,6 +961,8 @@ test_connection_filter (void)
|
|||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert_nonnull (c);
|
g_assert_nonnull (c);
|
||||||
|
|
||||||
|
data.incoming_queue = g_async_queue_new_full (g_object_unref);
|
||||||
|
data.num_outgoing = 0;
|
||||||
filter_id = g_dbus_connection_add_filter (c,
|
filter_id = g_dbus_connection_add_filter (c,
|
||||||
filter_func,
|
filter_func,
|
||||||
&data,
|
&data,
|
||||||
@ -965,21 +975,17 @@ test_connection_filter (void)
|
|||||||
g_dbus_message_set_body (m, g_variant_new ("(s)", "org.freedesktop.DBus"));
|
g_dbus_message_set_body (m, g_variant_new ("(s)", "org.freedesktop.DBus"));
|
||||||
error = NULL;
|
error = NULL;
|
||||||
g_dbus_connection_send_message (c, m, G_DBUS_SEND_MESSAGE_FLAGS_NONE, &serial_temp, &error);
|
g_dbus_connection_send_message (c, m, G_DBUS_SEND_MESSAGE_FLAGS_NONE, &serial_temp, &error);
|
||||||
g_atomic_int_set (&data.serial, serial_temp);
|
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
while (g_atomic_int_get (&data.num_handled) == 0)
|
wait_for_filtered_reply (data.incoming_queue, serial_temp);
|
||||||
g_thread_yield ();
|
|
||||||
|
|
||||||
m2 = g_dbus_message_copy (m, &error);
|
m2 = g_dbus_message_copy (m, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_dbus_connection_send_message (c, m2, G_DBUS_SEND_MESSAGE_FLAGS_NONE, &serial_temp, &error);
|
g_dbus_connection_send_message (c, m2, G_DBUS_SEND_MESSAGE_FLAGS_NONE, &serial_temp, &error);
|
||||||
g_atomic_int_set (&data.serial, serial_temp);
|
|
||||||
g_object_unref (m2);
|
g_object_unref (m2);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
while (g_atomic_int_get (&data.num_handled) == 1)
|
wait_for_filtered_reply (data.incoming_queue, serial_temp);
|
||||||
g_thread_yield ();
|
|
||||||
|
|
||||||
m2 = g_dbus_message_copy (m, &error);
|
m2 = g_dbus_message_copy (m, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
@ -987,12 +993,10 @@ test_connection_filter (void)
|
|||||||
/* lock the message to test PRESERVE_SERIAL flag. */
|
/* lock the message to test PRESERVE_SERIAL flag. */
|
||||||
g_dbus_message_lock (m2);
|
g_dbus_message_lock (m2);
|
||||||
g_dbus_connection_send_message (c, m2, G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL, &serial_temp, &error);
|
g_dbus_connection_send_message (c, m2, G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL, &serial_temp, &error);
|
||||||
g_atomic_int_set (&data.serial, serial_temp);
|
|
||||||
g_object_unref (m2);
|
g_object_unref (m2);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
while (g_atomic_int_get (&data.num_handled) == 2)
|
wait_for_filtered_reply (data.incoming_queue, serial_temp);
|
||||||
g_thread_yield ();
|
|
||||||
|
|
||||||
m2 = g_dbus_message_copy (m, &error);
|
m2 = g_dbus_message_copy (m, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
@ -1000,17 +1004,16 @@ test_connection_filter (void)
|
|||||||
m2,
|
m2,
|
||||||
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
/* can't do this write atomically
|
&serial_temp,
|
||||||
* as filter_func() needs it before
|
|
||||||
* send_message_with_reply_sync() returns */
|
|
||||||
&data.serial,
|
|
||||||
NULL, /* GCancellable */
|
NULL, /* GCancellable */
|
||||||
&error);
|
&error);
|
||||||
g_object_unref (m2);
|
g_object_unref (m2);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert_nonnull (r);
|
g_assert_nonnull (r);
|
||||||
g_object_unref (r);
|
g_object_unref (r);
|
||||||
g_assert_cmpint (g_atomic_int_get (&data.num_handled), ==, 4);
|
|
||||||
|
wait_for_filtered_reply (data.incoming_queue, serial_temp);
|
||||||
|
g_assert_cmpint (g_async_queue_length (data.incoming_queue), ==, 0);
|
||||||
|
|
||||||
g_dbus_connection_remove_filter (c, filter_id);
|
g_dbus_connection_remove_filter (c, filter_id);
|
||||||
|
|
||||||
@ -1023,12 +1026,11 @@ test_connection_filter (void)
|
|||||||
&serial_temp,
|
&serial_temp,
|
||||||
NULL, /* GCancellable */
|
NULL, /* GCancellable */
|
||||||
&error);
|
&error);
|
||||||
g_atomic_int_set (&data.serial, serial_temp);
|
|
||||||
g_object_unref (m2);
|
g_object_unref (m2);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert_nonnull (r);
|
g_assert_nonnull (r);
|
||||||
g_object_unref (r);
|
g_object_unref (r);
|
||||||
g_assert_cmpint (g_atomic_int_get (&data.num_handled), ==, 4);
|
g_assert_cmpint (g_async_queue_length (data.incoming_queue), ==, 0);
|
||||||
g_assert_cmpint (g_atomic_int_get (&data.num_outgoing), ==, 4);
|
g_assert_cmpint (g_atomic_int_get (&data.num_outgoing), ==, 4);
|
||||||
|
|
||||||
/* wait for service to be available */
|
/* wait for service to be available */
|
||||||
@ -1101,6 +1103,7 @@ test_connection_filter (void)
|
|||||||
|
|
||||||
g_object_unref (c);
|
g_object_unref (c);
|
||||||
g_object_unref (m);
|
g_object_unref (m);
|
||||||
|
g_async_queue_unref (data.incoming_queue);
|
||||||
|
|
||||||
session_bus_down ();
|
session_bus_down ();
|
||||||
}
|
}
|
||||||
@ -1268,9 +1271,6 @@ main (int argc,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* FIXME: Add debug for https://gitlab.gnome.org/GNOME/glib/issues/1957 */
|
|
||||||
g_setenv ("G_DBUS_DEBUG", "all", TRUE);
|
|
||||||
|
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
/* all the tests rely on a shared main loop */
|
/* all the tests rely on a shared main loop */
|
||||||
|
Loading…
Reference in New Issue
Block a user