[libsoup/carlosgc/thread-safe] 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] connection: attach the idle timeout source to the session context
- Date: Thu, 21 Apr 2022 13:08:50 +0000 (UTC)
commit 2dc0ffdb2d85b473f359fa14b760ca13d212e9e0
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 344162af..e954b3dc 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..0edc011c 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 tiemout");
+ 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]