tests: Fix unlikely race in socket-service test

It’s occasionally possible for the cancellation of the service to happen
before connection_cb() gets scheduled in the other thread. The
locking/unlocking order of mutex_712570 requires:
 • test_threaded_712570(): lock mutex
 • test_threaded_712570(): start wait loop
 • connection_cb(): lock mutex
 • test_threaded_socket_service_finalize(): unlock mutex
 • test_threaded_712570(): end wait loop
 • test_threaded_712570(): unlock mutex

Fix that by quitting the main loop once connection_cb() has been called
(i.e. once the server thread has received the incoming connection
request), rather than just after the client thread (main thread) has
sent a connection request.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

Helps: #1679
This commit is contained in:
Philip Withnall 2019-02-21 17:45:40 +00:00
parent 2aea9c84c0
commit f25c3f2704

View File

@ -139,6 +139,12 @@ connection_cb (GThreadedSocketService *service,
GObject *source_object, GObject *source_object,
gpointer user_data) gpointer user_data)
{ {
GMainLoop *loop = user_data;
/* Since the connection attempt has come through to be handled, stop the main
* thread waiting for it; this causes the #GSocketService to be stopped. */
g_main_loop_quit (loop);
/* Block until the main thread has dropped its ref to @service, so that we /* Block until the main thread has dropped its ref to @service, so that we
* will drop the final ref from this thread. * will drop the final ref from this thread.
*/ */
@ -158,7 +164,6 @@ client_connected_cb (GObject *client,
GAsyncResult *result, GAsyncResult *result,
gpointer user_data) gpointer user_data)
{ {
GMainLoop *loop = user_data;
GSocketConnection *conn; GSocketConnection *conn;
GError *error = NULL; GError *error = NULL;
@ -166,7 +171,6 @@ client_connected_cb (GObject *client,
g_assert_no_error (error); g_assert_no_error (error);
g_object_unref (conn); g_object_unref (conn);
g_main_loop_quit (loop);
} }
static void static void
@ -195,9 +199,8 @@ test_threaded_712570 (void)
g_assert_no_error (error); g_assert_no_error (error);
g_object_unref (addr); g_object_unref (addr);
g_signal_connect (service, "run", G_CALLBACK (connection_cb), NULL);
loop = g_main_loop_new (NULL, FALSE); loop = g_main_loop_new (NULL, FALSE);
g_signal_connect (service, "run", G_CALLBACK (connection_cb), loop);
client = g_socket_client_new (); client = g_socket_client_new ();
g_socket_client_connect_async (client, g_socket_client_connect_async (client,