mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-31 12:53:07 +02:00
gdbus-peer: Drop some usage of g_thread_yield()
It's a recipe for race conditions and error; on some hardware architectures one thread isn't guaranteed to see the results of writes from another thread without a cache flush. https://bugzilla.gnome.org/show_bug.cgi?id=700855
This commit is contained in:
parent
ff8f37ac05
commit
49030c8797
@ -66,6 +66,8 @@ static const gchar *datapath;
|
|||||||
|
|
||||||
static gchar *tmp_address = NULL;
|
static gchar *tmp_address = NULL;
|
||||||
static gchar *test_guid = NULL;
|
static gchar *test_guid = NULL;
|
||||||
|
static GMutex service_loop_lock;
|
||||||
|
static GCond service_loop_cond;
|
||||||
static GMainLoop *service_loop = NULL;
|
static GMainLoop *service_loop = NULL;
|
||||||
static GDBusServer *server = NULL;
|
static GDBusServer *server = NULL;
|
||||||
static GMainLoop *loop = NULL;
|
static GMainLoop *loop = NULL;
|
||||||
@ -344,6 +346,33 @@ on_new_connection (GDBusServer *server,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_service_loop (GMainContext *service_context)
|
||||||
|
{
|
||||||
|
g_assert (service_loop == NULL);
|
||||||
|
g_mutex_lock (&service_loop_lock);
|
||||||
|
service_loop = g_main_loop_new (service_context, FALSE);
|
||||||
|
g_cond_broadcast (&service_loop_cond);
|
||||||
|
g_mutex_unlock (&service_loop_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
teardown_service_loop (void)
|
||||||
|
{
|
||||||
|
g_mutex_lock (&service_loop_lock);
|
||||||
|
g_clear_pointer (&service_loop, g_main_loop_unref);
|
||||||
|
g_mutex_unlock (&service_loop_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
await_service_loop (void)
|
||||||
|
{
|
||||||
|
g_mutex_lock (&service_loop_lock);
|
||||||
|
while (service_loop == NULL)
|
||||||
|
g_cond_wait (&service_loop_cond, &service_loop_lock);
|
||||||
|
g_mutex_unlock (&service_loop_lock);
|
||||||
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
service_thread_func (gpointer user_data)
|
service_thread_func (gpointer user_data)
|
||||||
{
|
{
|
||||||
@ -399,12 +428,12 @@ service_thread_func (gpointer user_data)
|
|||||||
|
|
||||||
g_dbus_server_start (server);
|
g_dbus_server_start (server);
|
||||||
|
|
||||||
service_loop = g_main_loop_new (service_context, FALSE);
|
create_service_loop (service_context);
|
||||||
g_main_loop_run (service_loop);
|
g_main_loop_run (service_loop);
|
||||||
|
|
||||||
g_main_context_pop_thread_default (service_context);
|
g_main_context_pop_thread_default (service_context);
|
||||||
|
|
||||||
g_main_loop_unref (service_loop);
|
teardown_service_loop ();
|
||||||
g_main_context_unref (service_context);
|
g_main_context_unref (service_context);
|
||||||
|
|
||||||
/* test code specifically unrefs the server - see below */
|
/* test code specifically unrefs the server - see below */
|
||||||
@ -494,12 +523,12 @@ service_thread_func (gpointer data)
|
|||||||
data);
|
data);
|
||||||
g_socket_service_start (service);
|
g_socket_service_start (service);
|
||||||
|
|
||||||
service_loop = g_main_loop_new (service_context, FALSE);
|
create_service_loop (service_context);
|
||||||
g_main_loop_run (service_loop);
|
g_main_loop_run (service_loop);
|
||||||
|
|
||||||
g_main_context_pop_thread_default (service_context);
|
g_main_context_pop_thread_default (service_context);
|
||||||
|
|
||||||
g_main_loop_unref (service_loop);
|
teardown_service_loop ();
|
||||||
g_main_context_unref (service_context);
|
g_main_context_unref (service_context);
|
||||||
|
|
||||||
g_object_unref (address);
|
g_object_unref (address);
|
||||||
@ -649,12 +678,10 @@ test_peer (void)
|
|||||||
g_assert (c == NULL);
|
g_assert (c == NULL);
|
||||||
|
|
||||||
/* bring up a server - we run the server in a different thread to avoid deadlocks */
|
/* bring up a server - we run the server in a different thread to avoid deadlocks */
|
||||||
service_loop = NULL;
|
|
||||||
service_thread = g_thread_new ("test_peer",
|
service_thread = g_thread_new ("test_peer",
|
||||||
service_thread_func,
|
service_thread_func,
|
||||||
&data);
|
&data);
|
||||||
while (service_loop == NULL)
|
await_service_loop ();
|
||||||
g_thread_yield ();
|
|
||||||
g_assert (server != NULL);
|
g_assert (server != NULL);
|
||||||
|
|
||||||
/* bring up a connection and accept it */
|
/* bring up a connection and accept it */
|
||||||
@ -1213,12 +1240,12 @@ nonce_tcp_service_thread_func (gpointer user_data)
|
|||||||
|
|
||||||
g_dbus_server_start (server);
|
g_dbus_server_start (server);
|
||||||
|
|
||||||
service_loop = g_main_loop_new (service_context, FALSE);
|
create_service_loop (service_context);
|
||||||
g_main_loop_run (service_loop);
|
g_main_loop_run (service_loop);
|
||||||
|
|
||||||
g_main_context_pop_thread_default (service_context);
|
g_main_context_pop_thread_default (service_context);
|
||||||
|
|
||||||
g_main_loop_unref (service_loop);
|
teardown_service_loop ();
|
||||||
g_main_context_unref (service_context);
|
g_main_context_unref (service_context);
|
||||||
|
|
||||||
/* test code specifically unrefs the server - see below */
|
/* test code specifically unrefs the server - see below */
|
||||||
@ -1244,15 +1271,12 @@ test_nonce_tcp (void)
|
|||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
server = NULL;
|
server = NULL;
|
||||||
service_loop = NULL;
|
|
||||||
service_thread = g_thread_new ("nonce-tcp-service",
|
service_thread = g_thread_new ("nonce-tcp-service",
|
||||||
nonce_tcp_service_thread_func,
|
nonce_tcp_service_thread_func,
|
||||||
&data);
|
&data);
|
||||||
while (service_loop == NULL)
|
await_service_loop ();
|
||||||
g_thread_yield ();
|
|
||||||
g_assert (server != NULL);
|
g_assert (server != NULL);
|
||||||
|
|
||||||
|
|
||||||
/* bring up a connection and accept it */
|
/* bring up a connection and accept it */
|
||||||
data.accept_connection = TRUE;
|
data.accept_connection = TRUE;
|
||||||
error = NULL;
|
error = NULL;
|
||||||
@ -1532,12 +1556,12 @@ tcp_anonymous_service_thread_func (gpointer user_data)
|
|||||||
|
|
||||||
g_dbus_server_start (server);
|
g_dbus_server_start (server);
|
||||||
|
|
||||||
service_loop = g_main_loop_new (service_context, FALSE);
|
create_service_loop (service_context);
|
||||||
g_main_loop_run (service_loop);
|
g_main_loop_run (service_loop);
|
||||||
|
|
||||||
g_main_context_pop_thread_default (service_context);
|
g_main_context_pop_thread_default (service_context);
|
||||||
|
|
||||||
g_main_loop_unref (service_loop);
|
teardown_service_loop ();
|
||||||
g_main_context_unref (service_context);
|
g_main_context_unref (service_context);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1552,12 +1576,10 @@ test_tcp_anonymous (void)
|
|||||||
GError *error;
|
GError *error;
|
||||||
|
|
||||||
seen_connection = FALSE;
|
seen_connection = FALSE;
|
||||||
service_loop = NULL;
|
|
||||||
service_thread = g_thread_new ("tcp-anon-service",
|
service_thread = g_thread_new ("tcp-anon-service",
|
||||||
tcp_anonymous_service_thread_func,
|
tcp_anonymous_service_thread_func,
|
||||||
&seen_connection);
|
&seen_connection);
|
||||||
while (service_loop == NULL)
|
await_service_loop ();
|
||||||
g_thread_yield ();
|
|
||||||
g_assert (server != NULL);
|
g_assert (server != NULL);
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
@ -1690,14 +1712,14 @@ codegen_service_thread_func (gpointer user_data)
|
|||||||
G_CALLBACK (codegen_on_new_connection),
|
G_CALLBACK (codegen_on_new_connection),
|
||||||
animal);
|
animal);
|
||||||
|
|
||||||
service_loop = g_main_loop_new (service_context, FALSE);
|
create_service_loop (service_context);
|
||||||
g_main_loop_run (service_loop);
|
g_main_loop_run (service_loop);
|
||||||
|
|
||||||
g_object_unref (animal);
|
g_object_unref (animal);
|
||||||
|
|
||||||
g_main_context_pop_thread_default (service_context);
|
g_main_context_pop_thread_default (service_context);
|
||||||
|
|
||||||
g_main_loop_unref (service_loop);
|
teardown_service_loop ();
|
||||||
g_main_context_unref (service_context);
|
g_main_context_unref (service_context);
|
||||||
|
|
||||||
g_dbus_server_stop (codegen_server);
|
g_dbus_server_stop (codegen_server);
|
||||||
@ -1725,12 +1747,10 @@ codegen_test_peer (void)
|
|||||||
GVariant *value;
|
GVariant *value;
|
||||||
|
|
||||||
/* bring up a server - we run the server in a different thread to avoid deadlocks */
|
/* bring up a server - we run the server in a different thread to avoid deadlocks */
|
||||||
service_loop = NULL;
|
|
||||||
service_thread = g_thread_new ("codegen_test_peer",
|
service_thread = g_thread_new ("codegen_test_peer",
|
||||||
codegen_service_thread_func,
|
codegen_service_thread_func,
|
||||||
NULL);
|
NULL);
|
||||||
while (service_loop == NULL)
|
await_service_loop ();
|
||||||
g_thread_yield ();
|
|
||||||
g_assert (codegen_server != NULL);
|
g_assert (codegen_server != NULL);
|
||||||
|
|
||||||
/* Get an animal 1 ... */
|
/* Get an animal 1 ... */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user