[libsoup/carlosgc/thread-safe: 18/19] connection: attach the idle timeout source to the session context
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup/carlosgc/thread-safe: 18/19] connection: attach the idle timeout source to the session context
- Date: Tue, 3 May 2022 10:07:19 +0000 (UTC)
commit df4fde3929af4d3bb9ce03c42937eee1649ba6c5
Author: Carlos Garcia Campos <cgarcia igalia com>
Date: Thu Apr 21 15:04:47 2022 +0200
connection: attach the idle timeout source to the session context
The connection thread owner might change, so the context where the idle
timeout source was attached might be destroyed while the connection is
still alive. So, better use the session context always, since
disconnecting at idle state is always safe from the session thread.
libsoup/soup-connection-manager.c | 1 +
libsoup/soup-connection.c | 47 ++++++++++++++++++++++++---------------
libsoup/soup-session-private.h | 2 ++
libsoup/soup-session.c | 8 +++++++
4 files changed, 40 insertions(+), 18 deletions(-)
---
diff --git a/libsoup/soup-connection-manager.c b/libsoup/soup-connection-manager.c
index d5966655..a200f221 100644
--- a/libsoup/soup-connection-manager.c
+++ b/libsoup/soup-connection-manager.c
@@ -461,6 +461,7 @@ soup_connection_manager_get_connection_locked (SoupConnectionManager *manager,
socket_props = soup_session_ensure_socket_props (item->session);
conn = g_object_new (SOUP_TYPE_CONNECTION,
"id", ++manager->last_connection_id,
+ "context", soup_session_get_context (item->session),
"remote-connectable", remote_connectable,
"ssl", soup_uri_is_https (host->uri),
"socket-properties", socket_props,
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 64ee4afa..6e77ec72 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -77,13 +77,14 @@ enum {
PROP_TLS_PROTOCOL_VERSION,
PROP_TLS_CIPHERSUITE_NAME,
PROP_FORCE_HTTP_VERSION,
+ PROP_CONTEXT,
LAST_PROPERTY
};
static GParamSpec *properties[LAST_PROPERTY] = { NULL, };
-static void stop_idle_timer (SoupConnectionPrivate *priv);
+static gboolean idle_timeout (gpointer conn);
/* Number of seconds after which we close a connection that hasn't yet
* been used.
@@ -135,7 +136,11 @@ soup_connection_dispose (GObject *object)
SoupConnection *conn = SOUP_CONNECTION (object);
SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn);
- stop_idle_timer (priv);
+ if (priv->idle_timeout_src) {
+ g_source_destroy (priv->idle_timeout_src);
+ g_source_unref (priv->idle_timeout_src);
+ priv->idle_timeout_src = NULL;
+ }
G_OBJECT_CLASS (soup_connection_parent_class)->dispose (object);
}
@@ -162,6 +167,13 @@ soup_connection_set_property (GObject *object, guint prop_id,
case PROP_FORCE_HTTP_VERSION:
priv->force_http_version = g_value_get_uchar (value);
break;
+ case PROP_CONTEXT:
+ priv->idle_timeout_src = g_timeout_source_new (0);
+ g_source_set_ready_time (priv->idle_timeout_src, -1);
+ g_source_set_name (priv->idle_timeout_src, "Soup connection idle timeout");
+ g_source_set_callback (priv->idle_timeout_src, idle_timeout, object, NULL);
+ g_source_attach (priv->idle_timeout_src, g_value_get_pointer (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -354,6 +366,12 @@ soup_connection_class_init (SoupConnectionClass *connection_class)
0, G_MAXUINT8, G_MAXUINT8,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
+ properties[PROP_CONTEXT] =
+ g_param_spec_pointer ("context",
+ "Context",
+ "The session main context",
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, LAST_PROPERTY, properties);
}
@@ -373,7 +391,7 @@ static gboolean
idle_timeout (gpointer conn)
{
soup_connection_disconnect (conn);
- return FALSE;
+ return G_SOURCE_REMOVE;
}
static void
@@ -381,21 +399,14 @@ start_idle_timer (SoupConnection *conn)
{
SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn);
- if (priv->socket_props->idle_timeout > 0 && !priv->idle_timeout_src) {
- priv->idle_timeout_src =
- soup_add_timeout (g_main_context_get_thread_default (),
- priv->socket_props->idle_timeout * 1000,
- idle_timeout, conn);
- }
-}
+ if (priv->socket_props->idle_timeout == 0)
+ return;
-static void
-stop_idle_timer (SoupConnectionPrivate *priv)
-{
- if (priv->idle_timeout_src) {
- g_source_destroy (priv->idle_timeout_src);
- g_clear_pointer (&priv->idle_timeout_src, g_source_unref);
- }
+ if (g_source_get_ready_time (priv->idle_timeout_src) >= 0)
+ return;
+
+ g_source_set_ready_time (priv->idle_timeout_src,
+ g_get_monotonic_time () + (guint64)priv->socket_props->idle_timeout *
G_USEC_PER_SEC);
}
static void
@@ -1168,7 +1179,7 @@ soup_connection_setup_message_io (SoupConnection *conn,
g_assert (g_atomic_int_get (&priv->state) == SOUP_CONNECTION_IN_USE);
priv->unused_timeout = 0;
- stop_idle_timer (priv);
+ g_source_set_ready_time (priv->idle_timeout_src, -1);
if (priv->proxy_uri && soup_message_get_method (msg) == SOUP_METHOD_CONNECT)
set_proxy_msg (conn, msg);
diff --git a/libsoup/soup-session-private.h b/libsoup/soup-session-private.h
index 3ed380d1..77595c81 100644
--- a/libsoup/soup-session-private.h
+++ b/libsoup/soup-session-private.h
@@ -42,6 +42,8 @@ void soup_session_kick_queue (SoupSession *session);
SoupSocketProperties *soup_session_ensure_socket_props (SoupSession *session);
+GMainContext *soup_session_get_context (SoupSession *session);
+
G_END_DECLS
#endif /* __SOUP_SESSION_PRIVATE_H__ */
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 9d8b15d4..ef03cdab 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -359,6 +359,14 @@ soup_session_finalize (GObject *object)
G_OBJECT_CLASS (soup_session_parent_class)->finalize (object);
}
+GMainContext *
+soup_session_get_context (SoupSession *session)
+{
+ SoupSessionPrivate *priv = soup_session_get_instance_private (session);
+
+ return priv->context;
+}
+
SoupSocketProperties *
soup_session_ensure_socket_props (SoupSession *session)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]