From cfa0177b0aa37809c963e6a24455d77b0d163979 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 2 Jan 2023 14:06:02 +0100 Subject: soup-connection-auth: Add thread safety around 'conns' hash table The GHashTable is not thread safe, thus add a thread safety around it, to avoid issues when it's accessed from multiple threads at the same time. Closes https://gitlab.gnome.org/GNOME/libsoup/-/issues/317 --- libsoup/auth/soup-connection-auth.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/libsoup/auth/soup-connection-auth.c b/libsoup/auth/soup-connection-auth.c index cf36279e..2d9514f9 100644 --- a/libsoup/auth/soup-connection-auth.c +++ b/libsoup/auth/soup-connection-auth.c @@ -20,6 +20,7 @@ typedef struct { GHashTable *conns; + GMutex lock; } SoupConnectionAuthPrivate; G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (SoupConnectionAuth, soup_connection_auth, SOUP_TYPE_AUTH) @@ -29,6 +30,7 @@ soup_connection_auth_init (SoupConnectionAuth *auth) { SoupConnectionAuthPrivate *priv = soup_connection_auth_get_instance_private (auth); + g_mutex_init (&priv->lock); priv->conns = g_hash_table_new (NULL, NULL); } @@ -50,8 +52,10 @@ connection_disconnected (SoupConnection *conn, gpointer user_data) SoupConnectionAuthPrivate *priv = soup_connection_auth_get_instance_private (auth); gpointer state; + g_mutex_lock (&priv->lock); state = g_hash_table_lookup (priv->conns, conn); g_hash_table_remove (priv->conns, conn); + g_mutex_unlock (&priv->lock); soup_connection_auth_free_connection_state (auth, conn, state); } @@ -63,12 +67,15 @@ soup_connection_auth_finalize (GObject *object) GHashTableIter iter; gpointer conn, state; + g_mutex_lock (&priv->lock); g_hash_table_iter_init (&iter, priv->conns); while (g_hash_table_iter_next (&iter, &conn, &state)) { soup_connection_auth_free_connection_state (auth, conn, state); g_hash_table_iter_remove (&iter); } g_hash_table_destroy (priv->conns); + g_mutex_unlock (&priv->lock); + g_mutex_clear (&priv->lock); G_OBJECT_CLASS (soup_connection_auth_parent_class)->finalize (object); } @@ -99,16 +106,19 @@ soup_connection_auth_get_connection_state_for_message (SoupConnectionAuth *auth, g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL); conn = soup_message_get_connection (msg); + g_mutex_lock (&priv->lock); state = g_hash_table_lookup (priv->conns, conn); if (!state) { state = SOUP_CONNECTION_AUTH_GET_CLASS (auth)->create_connection_state (auth); + g_hash_table_insert (priv->conns, conn, state); + g_mutex_unlock (&priv->lock); if (conn) { g_signal_connect (conn, "disconnected", G_CALLBACK (connection_disconnected), auth); } - - g_hash_table_insert (priv->conns, conn, state); - } + } else { + g_mutex_unlock (&priv->lock); + } g_clear_object (&conn); return state; -- cgit v1.2.1