summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2023-01-11 12:14:27 +0100
committerCarlos Garcia Campos <carlosgc@gnome.org>2023-01-20 08:31:46 +0000
commitbea49ce848bcfc10d86cbf952f20d43110a6f2a7 (patch)
treeae78db6b4807948b3ed9874519201f930b386c4f
parent771bf193b67695a86a44c36ed7e20ae4bee66bda (diff)
downloadlibsoup-bea49ce848bcfc10d86cbf952f20d43110a6f2a7.tar.gz
connection-manager: free unused hosts always in the session context
And with the connection manager mutex locked.
-rw-r--r--libsoup/soup-connection-manager.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/libsoup/soup-connection-manager.c b/libsoup/soup-connection-manager.c
index a200f221..d0082981 100644
--- a/libsoup/soup-connection-manager.c
+++ b/libsoup/soup-connection-manager.c
@@ -33,27 +33,31 @@ struct _SoupConnectionManager {
typedef struct {
GUri *uri;
+ GMutex *mutex;
GHashTable *owner_map;
GNetworkAddress *addr;
GList *conns;
guint num_conns;
+ GMainContext *context;
GSource *keep_alive_src;
- SoupConnectionManager *conn_manager;
} SoupHost;
#define HOST_KEEP_ALIVE 5 * 60 * 1000 /* 5 min in msecs */
static SoupHost *
-soup_host_new (GUri *uri,
- GHashTable *owner_map)
+soup_host_new (GUri *uri,
+ GHashTable *owner_map,
+ GMutex *mutex,
+ GMainContext *context)
{
SoupHost *host;
const char *scheme = g_uri_get_scheme (uri);
host = g_new0 (SoupHost, 1);
host->owner_map = owner_map;
+ host->mutex = mutex;
if (g_strcmp0 (scheme, "http") != 0 && g_strcmp0 (scheme, "https") != 0) {
host->uri = soup_uri_copy (uri,
SOUP_URI_SCHEME, soup_uri_is_https (uri) ? "https" : "http",
@@ -67,6 +71,8 @@ soup_host_new (GUri *uri,
"scheme", g_uri_get_scheme (host->uri),
NULL);
+ host->context = context;
+
g_hash_table_insert (host->owner_map, host->uri, host);
return host;
@@ -123,14 +129,20 @@ static gboolean
free_unused_host (gpointer user_data)
{
SoupHost *host = (SoupHost *)user_data;
+ GMutex *mutex = host->mutex;
- if (host->conns)
- return FALSE;
+ g_mutex_lock (mutex);
- /* This will free the host in addition to removing it from the hash table */
- g_hash_table_remove (host->owner_map, host->uri);
+ g_clear_pointer (&host->keep_alive_src, g_source_unref);
- return FALSE;
+ if (!host->conns) {
+ /* This will free the host in addition to removing it from the hash table */
+ g_hash_table_remove (host->owner_map, host->uri);
+ }
+
+ g_mutex_unlock (mutex);
+
+ return G_SOURCE_REMOVE;
}
static void
@@ -160,7 +172,7 @@ soup_host_remove_connection (SoupHost *host,
*/
if (host->num_conns == 0) {
g_assert (host->keep_alive_src == NULL);
- host->keep_alive_src = soup_add_timeout (g_main_context_get_thread_default (),
+ host->keep_alive_src = soup_add_timeout (host->context,
HOST_KEEP_ALIVE,
free_unused_host,
host);
@@ -172,13 +184,24 @@ soup_connection_manager_get_host_for_message (SoupConnectionManager *manager,
SoupMessage *msg)
{
GUri *uri = soup_message_get_uri (msg);
- SoupHost *host;
GHashTable *map;
map = soup_uri_is_https (uri) ? manager->https_hosts : manager->http_hosts;
+ return g_hash_table_lookup (map, uri);
+}
+
+static SoupHost *
+soup_connection_manager_get_or_create_host_for_item (SoupConnectionManager *manager,
+ SoupMessageQueueItem *item)
+{
+ GUri *uri = soup_message_get_uri (item->msg);
+ GHashTable *map;
+ SoupHost *host;
+
+ map = soup_uri_is_https (uri) ? manager->https_hosts : manager->http_hosts;
host = g_hash_table_lookup (map, uri);
if (!host)
- host = soup_host_new (uri, map);
+ host = soup_host_new (uri, map, &manager->mutex, soup_session_get_context (item->session));
return host;
}
@@ -371,7 +394,7 @@ soup_connection_manager_get_connection_locked (SoupConnectionManager *manager,
(!soup_message_query_flags (msg, SOUP_MESSAGE_IDEMPOTENT) &&
!SOUP_METHOD_IS_IDEMPOTENT (soup_message_get_method (msg)));
- host = soup_connection_manager_get_host_for_message (manager, msg);
+ host = soup_connection_manager_get_or_create_host_for_item (manager, item);
force_http_version = g_getenv ("SOUP_FORCE_HTTP1") ? SOUP_HTTP_1_1 : soup_message_get_force_http_version (msg);
while (TRUE) {