summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2022-04-20 12:32:28 +0200
committerCarlos Garcia Campos <cgarcia@igalia.com>2022-06-08 12:36:17 +0200
commit2479d9f7ea17a4f8311e3fc73c6dffa3e59349c4 (patch)
treef0b4f1bb526225990183790d7f58034d70859266
parent05d07ee44f69cf93d1abb98d88aa7688b4cb6fdb (diff)
downloadlibsoup-2479d9f7ea17a4f8311e3fc73c6dffa3e59349c4.tar.gz
Use GWeakRef instead of g_object_add_weak_pointer()
GWeakRef is thread safe
-rw-r--r--libsoup/auth/soup-connection-auth.c17
-rw-r--r--libsoup/auth/soup-tls-interaction.c31
-rw-r--r--libsoup/http1/soup-client-message-io-http1.c5
-rw-r--r--libsoup/http2/soup-client-message-io-http2.c43
-rw-r--r--libsoup/soup-connection-manager.c9
-rw-r--r--libsoup/soup-logger.c7
-rw-r--r--libsoup/soup-message-queue-item.c3
-rw-r--r--libsoup/soup-message.c118
-rw-r--r--libsoup/soup-session.c49
9 files changed, 187 insertions, 95 deletions
diff --git a/libsoup/auth/soup-connection-auth.c b/libsoup/auth/soup-connection-auth.c
index 4bfb0ef7..cf36279e 100644
--- a/libsoup/auth/soup-connection-auth.c
+++ b/libsoup/auth/soup-connection-auth.c
@@ -100,16 +100,17 @@ soup_connection_auth_get_connection_state_for_message (SoupConnectionAuth *auth,
conn = soup_message_get_connection (msg);
state = g_hash_table_lookup (priv->conns, conn);
- if (state)
- return state;
+ if (!state) {
+ state = SOUP_CONNECTION_AUTH_GET_CLASS (auth)->create_connection_state (auth);
+ if (conn) {
+ g_signal_connect (conn, "disconnected",
+ G_CALLBACK (connection_disconnected), auth);
+ }
- state = SOUP_CONNECTION_AUTH_GET_CLASS (auth)->create_connection_state (auth);
- if (conn) {
- g_signal_connect (conn, "disconnected",
- G_CALLBACK (connection_disconnected), auth);
- }
+ g_hash_table_insert (priv->conns, conn, state);
+ }
+ g_clear_object (&conn);
- g_hash_table_insert (priv->conns, conn, state);
return state;
}
diff --git a/libsoup/auth/soup-tls-interaction.c b/libsoup/auth/soup-tls-interaction.c
index 1f683d88..6e333935 100644
--- a/libsoup/auth/soup-tls-interaction.c
+++ b/libsoup/auth/soup-tls-interaction.c
@@ -16,7 +16,7 @@ struct _SoupTlsInteraction {
};
typedef struct {
- SoupConnection *conn;
+ GWeakRef conn;
} SoupTlsInteractionPrivate;
G_DEFINE_FINAL_TYPE_WITH_PRIVATE (SoupTlsInteraction, soup_tls_interaction, G_TYPE_TLS_INTERACTION)
@@ -31,12 +31,15 @@ soup_tls_interaction_request_certificate_async (GTlsInteraction *tls
{
SoupTlsInteractionPrivate *priv = soup_tls_interaction_get_instance_private (SOUP_TLS_INTERACTION (tls_interaction));
GTask *task;
+ SoupConnection *conn = g_weak_ref_get (&priv->conn);
task = g_task_new (tls_interaction, cancellable, callback, user_data);
- if (priv->conn)
- soup_connection_request_tls_certificate (priv->conn, connection, task);
- else
+ if (conn) {
+ soup_connection_request_tls_certificate (conn, connection, task);
+ g_object_unref (conn);
+ } else {
g_task_return_int (task, G_TLS_INTERACTION_FAILED);
+ }
g_object_unref (task);
}
@@ -60,12 +63,15 @@ soup_tls_interaction_ask_password_async (GTlsInteraction *tls_interaction,
{
SoupTlsInteractionPrivate *priv = soup_tls_interaction_get_instance_private (SOUP_TLS_INTERACTION (tls_interaction));
GTask *task;
+ SoupConnection *conn = g_weak_ref_get (&priv->conn);
task = g_task_new (tls_interaction, cancellable, callback, user_data);
- if (priv->conn)
- soup_connection_request_tls_certificate_password (priv->conn, password, task);
- else
+ if (conn) {
+ soup_connection_request_tls_certificate_password (conn, password, task);
+ g_object_unref (conn);
+ } else {
g_task_return_int (task, G_TLS_INTERACTION_FAILED);
+ }
g_object_unref (task);
}
@@ -85,10 +91,7 @@ soup_tls_interaction_finalize (GObject *object)
{
SoupTlsInteractionPrivate *priv = soup_tls_interaction_get_instance_private (SOUP_TLS_INTERACTION (object));
- if (priv->conn) {
- g_object_remove_weak_pointer (G_OBJECT (priv->conn), (gpointer*)&priv->conn);
- priv->conn = NULL;
- }
+ g_weak_ref_clear (&priv->conn);
G_OBJECT_CLASS (soup_tls_interaction_parent_class)->finalize (object);
}
@@ -96,6 +99,9 @@ soup_tls_interaction_finalize (GObject *object)
static void
soup_tls_interaction_init (SoupTlsInteraction *interaction)
{
+ SoupTlsInteractionPrivate *priv = soup_tls_interaction_get_instance_private (interaction);
+
+ g_weak_ref_init (&priv->conn, NULL);
}
static void
@@ -120,8 +126,7 @@ soup_tls_interaction_new (SoupConnection *conn)
interaction = g_object_new (SOUP_TYPE_TLS_INTERACTION, NULL);
priv = soup_tls_interaction_get_instance_private (SOUP_TLS_INTERACTION (interaction));
- priv->conn = conn;
- g_object_add_weak_pointer (G_OBJECT (priv->conn), (gpointer*)&priv->conn);
+ g_weak_ref_set (&priv->conn, conn);
return interaction;
}
diff --git a/libsoup/http1/soup-client-message-io-http1.c b/libsoup/http1/soup-client-message-io-http1.c
index 1f421d6d..dff6bbf2 100644
--- a/libsoup/http1/soup-client-message-io-http1.c
+++ b/libsoup/http1/soup-client-message-io-http1.c
@@ -258,7 +258,10 @@ write_headers (SoupMessage *msg,
uri_string = g_strdup_printf ("%s:%d", uri_host, g_uri_get_port (uri));
g_free (uri_host);
} else {
- gboolean proxy = soup_connection_is_via_proxy (soup_message_get_connection (msg));
+ SoupConnection *conn = soup_message_get_connection (msg);
+ gboolean proxy = soup_connection_is_via_proxy (conn);
+
+ g_object_unref (conn);
/* Proxy expects full URI to destination. Otherwise
* just the path.
diff --git a/libsoup/http2/soup-client-message-io-http2.c b/libsoup/http2/soup-client-message-io-http2.c
index fe6aeaab..f62c20a8 100644
--- a/libsoup/http2/soup-client-message-io-http2.c
+++ b/libsoup/http2/soup-client-message-io-http2.c
@@ -64,7 +64,7 @@ typedef struct {
GThread *owner;
gboolean async;
- SoupConnection *conn;
+ GWeakRef conn;
GIOStream *stream;
GInputStream *istream;
GOutputStream *ostream;
@@ -469,6 +469,7 @@ io_read_ready (GObject *stream,
{
GError *error = NULL;
gboolean progress = TRUE;
+ SoupConnection *conn;
if (io->error) {
g_clear_pointer (&io->read_source, g_source_unref);
@@ -478,8 +479,9 @@ io_read_ready (GObject *stream,
/* Mark the connection as in use to make sure it's not disconnected while
* processing pending messages, for example if a goaway is received.
*/
- if (io->conn)
- soup_connection_set_in_use (io->conn, TRUE);
+ conn = g_weak_ref_get (&io->conn);
+ if (conn)
+ soup_connection_set_in_use (conn, TRUE);
while (nghttp2_session_want_read (io->session) && progress) {
progress = io_read (io, FALSE, NULL, &error);
@@ -492,8 +494,10 @@ io_read_ready (GObject *stream,
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
g_error_free (error);
- if (io->conn)
- soup_connection_set_in_use (io->conn, FALSE);
+ if (conn) {
+ soup_connection_set_in_use (conn, FALSE);
+ g_object_unref (conn);
+ }
return G_SOURCE_CONTINUE;
}
@@ -507,8 +511,10 @@ io_read_ready (GObject *stream,
io->is_shutdown = TRUE;
g_clear_pointer (&io->read_source, g_source_unref);
- if (io->conn)
- soup_connection_set_in_use (io->conn, FALSE);
+ if (conn) {
+ soup_connection_set_in_use (conn, FALSE);
+ g_object_unref (conn);
+ }
return G_SOURCE_REMOVE;
}
@@ -911,8 +917,12 @@ on_frame_send_callback (nghttp2_session *session,
case NGHTTP2_RST_STREAM:
h2_debug (io, data, "[SEND] [RST_STREAM] stream_id=%u", frame->hd.stream_id);
if (g_hash_table_foreach_remove (io->closed_messages, (GHRFunc)remove_closed_stream, (gpointer)frame)) {
- if (io->conn)
- soup_connection_set_in_use (io->conn, FALSE);
+ SoupConnection *conn = g_weak_ref_get (&io->conn);
+
+ if (conn) {
+ soup_connection_set_in_use (conn, FALSE);
+ g_object_unref (conn);
+ }
}
break;
@@ -1426,6 +1436,8 @@ soup_client_message_io_http2_finished (SoupClientMessageIO *iface,
nghttp2_session_set_stream_user_data (io->session, data->stream_id, NULL);
if (!io->is_shutdown) {
+ SoupConnection *conn;
+
NGCHECK (nghttp2_submit_rst_stream (io->session, NGHTTP2_FLAG_NONE, data->stream_id,
completion == SOUP_MESSAGE_IO_COMPLETE ? NGHTTP2_NO_ERROR : NGHTTP2_CANCEL));
soup_http2_message_data_close (data);
@@ -1435,8 +1447,11 @@ soup_client_message_io_http2_finished (SoupClientMessageIO *iface,
if (!g_hash_table_add (io->closed_messages, data))
g_warn_if_reached ();
- if (io->conn)
- soup_connection_set_in_use (io->conn, TRUE);
+ conn = g_weak_ref_get (&io->conn);
+ if (conn) {
+ soup_connection_set_in_use (conn, TRUE);
+ g_object_unref (conn);
+ }
io_try_write (io, !io->async);
} else {
@@ -1784,8 +1799,7 @@ soup_client_message_io_http2_destroy (SoupClientMessageIO *iface)
g_source_unref (io->write_source);
}
- if (io->conn)
- g_object_remove_weak_pointer (G_OBJECT (io->conn), (gpointer*)&io->conn);
+ g_weak_ref_clear (&io->conn);
g_clear_object (&io->stream);
g_clear_object (&io->close_task);
g_clear_pointer (&io->session, nghttp2_session_del);
@@ -1883,8 +1897,7 @@ soup_client_message_io_http2_new (SoupConnection *conn)
SoupClientMessageIOHTTP2 *io = g_new0 (SoupClientMessageIOHTTP2, 1);
soup_client_message_io_http2_init (io);
- io->conn = conn;
- g_object_add_weak_pointer (G_OBJECT (io->conn), (gpointer*)&io->conn);
+ g_weak_ref_init (&io->conn, conn);
io->stream = g_object_ref (soup_connection_get_iostream (conn));
io->istream = g_io_stream_get_input_stream (io->stream);
diff --git a/libsoup/soup-connection-manager.c b/libsoup/soup-connection-manager.c
index bdf4d291..d5966655 100644
--- a/libsoup/soup-connection-manager.c
+++ b/libsoup/soup-connection-manager.c
@@ -493,6 +493,7 @@ soup_connection_manager_get_connection (SoupConnectionManager *manager,
conn = soup_message_get_connection (item->msg);
if (conn) {
g_warn_if_fail (soup_connection_get_state (conn) != SOUP_CONNECTION_DISCONNECTED);
+ g_object_unref (conn);
return conn;
}
@@ -533,10 +534,14 @@ soup_connection_manager_steal_connection (SoupConnectionManager *manager,
GIOStream *stream;
conn = soup_message_get_connection (msg);
- if (!conn || soup_connection_get_state (conn) != SOUP_CONNECTION_IN_USE)
+ if (!conn)
return NULL;
- g_object_ref (conn);
+ if (soup_connection_get_state (conn) != SOUP_CONNECTION_IN_USE) {
+ g_object_unref (conn);
+ return NULL;
+ }
+
g_mutex_lock (&manager->mutex);
host = soup_connection_manager_get_host_for_message (manager, msg);
g_hash_table_remove (manager->conns, conn);
diff --git a/libsoup/soup-logger.c b/libsoup/soup-logger.c
index f26d7c13..2fd6d5a2 100644
--- a/libsoup/soup-logger.c
+++ b/libsoup/soup-logger.c
@@ -839,7 +839,7 @@ wrote_body (SoupMessage *msg, gpointer user_data)
gboolean restarted;
guint msg_id;
SoupConnection *conn;
- GSocket *socket;
+ GSocket *socket = NULL;
msg_id = soup_logger_get_id (logger, msg);
if (msg_id)
@@ -853,7 +853,10 @@ wrote_body (SoupMessage *msg, gpointer user_data)
soup_logger_set_id (logger, priv->session);
conn = soup_message_get_connection (msg);
- socket = conn ? soup_connection_get_socket (conn) : NULL;
+ if (conn) {
+ socket = soup_connection_get_socket (conn);
+ g_object_unref (conn);
+ }
if (socket && !soup_logger_get_id (logger, socket))
soup_logger_set_id (logger, socket);
diff --git a/libsoup/soup-message-queue-item.c b/libsoup/soup-message-queue-item.c
index 825fc022..3b4b4bbf 100644
--- a/libsoup/soup-message-queue-item.c
+++ b/libsoup/soup-message-queue-item.c
@@ -42,8 +42,9 @@ soup_message_queue_item_ref (SoupMessageQueueItem *item)
static void
soup_message_queue_item_destroy (SoupMessageQueueItem *item)
{
- if (!g_error_matches (item->error, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_MESSAGE_ALREADY_IN_QUEUE))
+ if (!g_error_matches (item->error, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_MESSAGE_ALREADY_IN_QUEUE)) {
g_warn_if_fail (soup_message_get_connection (item->msg) == NULL);
+ }
g_object_unref (item->session);
g_object_unref (item->msg);
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index f8d2c3e4..45ad8738 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -71,7 +71,7 @@ typedef struct {
GUri *uri;
SoupAuth *auth, *proxy_auth;
- SoupConnection *connection;
+ GWeakRef connection;
GHashTable *disabled_features;
@@ -168,6 +168,8 @@ soup_message_init (SoupMessage *msg)
priv->request_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST);
priv->response_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE);
+
+ g_weak_ref_init (&priv->connection, NULL);
}
static void
@@ -189,6 +191,7 @@ soup_message_finalize (GObject *object)
g_clear_object (&priv->pending_tls_cert_password);
soup_message_set_connection (msg, NULL);
+ g_weak_ref_clear (&priv->connection);
g_clear_pointer (&priv->uri, g_uri_unref);
g_clear_pointer (&priv->first_party, g_uri_unref);
@@ -1452,8 +1455,17 @@ soup_message_get_uri_for_auth (SoupMessage *msg)
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
if (priv->status_code == SOUP_STATUS_PROXY_UNAUTHORIZED) {
+ SoupConnection *connection = g_weak_ref_get (&priv->connection);
+
/* When loaded from the disk cache, the connection is NULL. */
- return priv->connection ? soup_connection_get_proxy_uri (priv->connection) : NULL;
+ if (connection) {
+ GUri *uri = soup_connection_get_proxy_uri (connection);
+
+ g_object_unref (connection);
+ return uri;
+ }
+
+ return NULL;
}
return priv->uri;
@@ -1524,7 +1536,7 @@ soup_message_get_connection (SoupMessage *msg)
{
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
- return priv->connection;
+ return g_weak_ref_get (&priv->connection);
}
static void
@@ -1671,67 +1683,68 @@ soup_message_set_connection (SoupMessage *msg,
SoupConnection *conn)
{
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+ SoupConnection *connection = g_weak_ref_get (&priv->connection);
- if (priv->connection == conn)
+ if (connection == conn) {
+ g_clear_object (&connection);
return;
+ }
- if (priv->connection) {
- g_signal_handlers_disconnect_by_data (priv->connection, msg);
+ if (connection) {
+ g_signal_handlers_disconnect_by_data (connection, msg);
priv->io_data = NULL;
if (priv->pending_tls_cert_request) {
- soup_connection_complete_tls_certificate_request (priv->connection,
+ soup_connection_complete_tls_certificate_request (connection,
priv->tls_client_certificate,
g_steal_pointer (&priv->pending_tls_cert_request));
g_clear_object (&priv->tls_client_certificate);
}
- g_object_remove_weak_pointer (G_OBJECT (priv->connection), (gpointer*)&priv->connection);
- soup_connection_set_in_use (priv->connection, FALSE);
+ soup_connection_set_in_use (connection, FALSE);
+ g_object_unref (connection);
}
- priv->connection = conn;
- if (!priv->connection)
+ g_weak_ref_set (&priv->connection, conn);
+ if (!conn)
return;
- soup_connection_set_in_use (priv->connection, TRUE);
- priv->last_connection_id = soup_connection_get_id (priv->connection);
+ soup_connection_set_in_use (conn, TRUE);
+ priv->last_connection_id = soup_connection_get_id (conn);
- g_object_add_weak_pointer (G_OBJECT (priv->connection), (gpointer*)&priv->connection);
soup_message_set_tls_peer_certificate (msg,
- soup_connection_get_tls_certificate (priv->connection),
- soup_connection_get_tls_certificate_errors (priv->connection));
+ soup_connection_get_tls_certificate (conn),
+ soup_connection_get_tls_certificate_errors (conn));
soup_message_set_tls_protocol_version (msg, soup_connection_get_tls_protocol_version (conn));
soup_message_set_tls_ciphersuite_name (msg, soup_connection_get_tls_ciphersuite_name (conn));
- soup_message_set_remote_address (msg, soup_connection_get_remote_address (priv->connection));
+ soup_message_set_remote_address (msg, soup_connection_get_remote_address (conn));
if (priv->tls_client_certificate) {
- soup_connection_set_tls_client_certificate (priv->connection,
- priv->tls_client_certificate);
+ soup_connection_set_tls_client_certificate (conn, priv->tls_client_certificate);
g_clear_object (&priv->tls_client_certificate);
}
- g_signal_connect_object (priv->connection, "event",
+ g_signal_connect_object (conn, "event",
G_CALLBACK (re_emit_connection_event),
msg, G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->connection, "accept-certificate",
+ g_signal_connect_object (conn, "accept-certificate",
G_CALLBACK (re_emit_accept_certificate),
msg, G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->connection, "request-certificate",
+ g_signal_connect_object (conn, "request-certificate",
G_CALLBACK (re_emit_request_certificate),
msg, G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->connection, "request-certificate-password",
+ g_signal_connect_object (conn, "request-certificate-password",
G_CALLBACK (re_emit_request_certificate_password),
msg, G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->connection, "notify::tls-certificate",
+ g_signal_connect_object (conn, "notify::tls-certificate",
G_CALLBACK (re_emit_tls_certificate_changed),
msg, G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->connection, "notify::tls-protocol-version",
+ g_signal_connect_object (conn, "notify::tls-protocol-version",
G_CALLBACK (connection_tls_protocol_version_changed),
msg, G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->connection, "notify::tls-ciphersuite-name",
+ g_signal_connect_object (conn, "notify::tls-ciphersuite-name",
G_CALLBACK (connection_tls_ciphersuite_name_changed),
msg, G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->connection, "notify::remote-address",
+ g_signal_connect_object (conn, "notify::remote-address",
G_CALLBACK (connection_remote_address_changed),
msg, G_CONNECT_SWAPPED);
}
@@ -1752,18 +1765,20 @@ soup_message_transfer_connection (SoupMessage *preconnect_msg,
SoupMessagePrivate *preconnect_priv = soup_message_get_instance_private (preconnect_msg);
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
GTlsCertificate *client_certificate = NULL;
+ SoupConnection *connection;
g_assert (preconnect_priv->is_preconnect);
- g_assert (!priv->connection);
+ g_assert (!g_weak_ref_get (&priv->connection));
client_certificate = g_steal_pointer (&priv->tls_client_certificate);
- soup_message_set_connection (msg, preconnect_priv->connection);
+ connection = g_weak_ref_get (&preconnect_priv->connection);
+ soup_message_set_connection (msg, connection);
/* If connection has pending interactions, transfer them too */
g_assert (!priv->pending_tls_cert_request);
priv->pending_tls_cert_request = g_steal_pointer (&preconnect_priv->pending_tls_cert_request);
if (priv->pending_tls_cert_request) {
if (client_certificate) {
- soup_connection_complete_tls_certificate_request (priv->connection,
+ soup_connection_complete_tls_certificate_request (connection,
client_certificate,
g_steal_pointer (&priv->pending_tls_cert_request));
g_object_unref (client_certificate);
@@ -1776,7 +1791,7 @@ soup_message_transfer_connection (SoupMessage *preconnect_msg,
g_clear_object (&priv->pending_tls_cert_request);
}
} else if (client_certificate) {
- soup_connection_set_tls_client_certificate (priv->connection, client_certificate);
+ soup_connection_set_tls_client_certificate (connection, client_certificate);
g_object_unref (client_certificate);
}
@@ -1792,6 +1807,7 @@ soup_message_transfer_connection (SoupMessage *preconnect_msg,
}
soup_message_set_connection (preconnect_msg, NULL);
+ g_object_unref (connection);
}
gboolean
@@ -1824,6 +1840,7 @@ void
soup_message_cleanup_response (SoupMessage *msg)
{
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+ SoupConnection *connection;
g_object_freeze_notify (G_OBJECT (msg));
@@ -1832,12 +1849,15 @@ soup_message_cleanup_response (SoupMessage *msg)
soup_message_set_status (msg, SOUP_STATUS_NONE, NULL);
soup_message_set_http_version (msg, priv->orig_http_version);
- if (!priv->connection) {
+ connection = g_weak_ref_get (&priv->connection);
+ if (!connection) {
soup_message_set_tls_peer_certificate (msg, NULL, 0);
soup_message_set_tls_protocol_version (msg, G_TLS_PROTOCOL_VERSION_UNKNOWN);
soup_message_set_tls_ciphersuite_name (msg, NULL);
soup_message_set_remote_address (msg, NULL);
priv->last_connection_id = 0;
+ } else {
+ g_object_unref (connection);
}
g_object_thaw_notify (G_OBJECT (msg));
@@ -2536,22 +2556,25 @@ soup_message_set_tls_client_certificate (SoupMessage *msg,
GTlsCertificate *certificate)
{
SoupMessagePrivate *priv;
+ SoupConnection *connection;
g_return_if_fail (SOUP_IS_MESSAGE (msg));
g_return_if_fail (certificate == NULL || G_IS_TLS_CERTIFICATE (certificate));
priv = soup_message_get_instance_private (msg);
+ connection = g_weak_ref_get (&priv->connection);
if (priv->pending_tls_cert_request) {
- g_assert (SOUP_IS_CONNECTION (priv->connection));
- soup_connection_complete_tls_certificate_request (priv->connection,
+ g_assert (SOUP_IS_CONNECTION (connection));
+ soup_connection_complete_tls_certificate_request (connection,
certificate,
g_steal_pointer (&priv->pending_tls_cert_request));
+ g_object_unref (connection);
return;
}
- if (priv->connection) {
- soup_connection_set_tls_client_certificate (priv->connection,
- certificate);
+ if (connection) {
+ soup_connection_set_tls_client_certificate (connection, certificate);
+ g_object_unref (connection);
return;
}
@@ -2576,6 +2599,7 @@ void
soup_message_tls_client_certificate_password_request_complete (SoupMessage *msg)
{
SoupMessagePrivate *priv;
+ SoupConnection *connection;
g_return_if_fail (SOUP_IS_MESSAGE (msg));
@@ -2585,9 +2609,11 @@ soup_message_tls_client_certificate_password_request_complete (SoupMessage *msg)
return;
}
- g_assert (SOUP_IS_CONNECTION (priv->connection));
- soup_connection_complete_tls_certificate_password_request (priv->connection,
+ connection = g_weak_ref_get (&priv->connection);
+ g_assert (SOUP_IS_CONNECTION (connection));
+ soup_connection_complete_tls_certificate_password_request (connection,
g_steal_pointer (&priv->pending_tls_cert_pass_request));
+ g_object_unref (connection);
}
/**
@@ -2681,7 +2707,12 @@ soup_message_io_finished (SoupMessage *msg)
if (!priv->io_data)
return;
- g_assert (priv->connection != NULL);
+#ifndef G_DISABLE_ASSERT
+ SoupConnection *connection = g_weak_ref_get (&priv->connection);
+
+ g_assert (connection != NULL);
+ g_object_unref (connection);
+#endif
soup_client_message_io_finished (g_steal_pointer (&priv->io_data), msg);
}
@@ -2797,10 +2828,11 @@ soup_message_send_item (SoupMessage *msg,
gpointer user_data)
{
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+ SoupConnection *connection = g_weak_ref_get (&priv->connection);
- priv->io_data = soup_connection_setup_message_io (priv->connection, msg);
- soup_client_message_io_send_item (priv->io_data, item,
- completion_cb, user_data);
+ priv->io_data = soup_connection_setup_message_io (connection, msg);
+ g_object_unref (connection);
+ soup_client_message_io_send_item (priv->io_data, item, completion_cb, user_data);
}
GInputStream *
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 387f71f3..4cd942e7 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -1070,7 +1070,13 @@ static int
lookup_connection (SoupMessageQueueItem *item,
SoupConnection *conn)
{
- return soup_message_get_connection (item->msg) == conn ? 0 : 1;
+ SoupConnection *connection = soup_message_get_connection (item->msg);
+ int retval;
+
+ retval = connection == conn ? 0 : 1;
+ g_clear_object (&connection);
+
+ return retval;
}
static SoupMessageQueueItem *
@@ -1260,6 +1266,7 @@ message_restarted (SoupMessage *msg, gpointer user_data)
SOUP_STATUS_IS_REDIRECTION (soup_message_get_status (msg)))) {
soup_message_set_connection (item->msg, NULL);
}
+ g_clear_object (&conn);
soup_message_cleanup_response (msg);
}
@@ -1348,6 +1355,7 @@ soup_session_send_queue_item (SoupSession *session,
SoupSessionPrivate *priv = soup_session_get_instance_private (session);
SoupMessageHeaders *request_headers;
const char *method;
+ SoupConnection *conn;
g_assert (item->context == soup_thread_default_context ());
@@ -1358,7 +1366,9 @@ soup_session_send_queue_item (SoupSession *session,
if (priv->accept_language && !soup_message_headers_get_list_common (request_headers, SOUP_HEADER_ACCEPT_LANGUAGE))
soup_message_headers_append_common (request_headers, SOUP_HEADER_ACCEPT_LANGUAGE, priv->accept_language);
- soup_message_set_http_version (item->msg, soup_connection_get_negotiated_protocol (soup_message_get_connection (item->msg)));
+ conn = soup_message_get_connection (item->msg);
+ soup_message_set_http_version (item->msg, soup_connection_get_negotiated_protocol (conn));
+ g_object_unref (conn);
soup_message_force_keep_alive_if_needed (item->msg);
soup_message_update_request_host_if_needed (item->msg);
@@ -1462,7 +1472,10 @@ tunnel_complete (SoupMessageQueueItem *tunnel_item,
item->error = error;
if (!SOUP_STATUS_IS_SUCCESSFUL (status) || item->error) {
- soup_connection_disconnect (soup_message_get_connection (item->msg));
+ SoupConnection *conn = soup_message_get_connection (item->msg);
+
+ soup_connection_disconnect (conn);
+ g_object_unref (conn);
soup_message_set_connection (item->msg, NULL);
if (!error && soup_message_get_status (item->msg) == SOUP_STATUS_NONE)
soup_message_set_status (item->msg, status, NULL);
@@ -1499,8 +1512,13 @@ tunnel_message_completed (SoupMessage *msg, SoupMessageIOCompletion completion,
tunnel_item->state = SOUP_MESSAGE_RESTARTING;
if (tunnel_item->state == SOUP_MESSAGE_RESTARTING) {
+ SoupConnection *conn;
+
soup_message_restarted (msg);
- if (soup_message_get_connection (tunnel_item->msg)) {
+
+ conn = soup_message_get_connection (tunnel_item->msg);
+ if (conn) {
+ g_object_unref (conn);
tunnel_item->state = SOUP_MESSAGE_RUNNING;
soup_session_send_queue_item (session, tunnel_item,
(SoupMessageIOCompletionFn)tunnel_message_completed);
@@ -1521,15 +1539,20 @@ tunnel_message_completed (SoupMessage *msg, SoupMessageIOCompletion completion,
}
if (tunnel_item->async) {
- soup_connection_tunnel_handshake_async (soup_message_get_connection (item->msg),
+ SoupConnection *conn = soup_message_get_connection (item->msg);
+
+ soup_connection_tunnel_handshake_async (conn,
item->io_priority,
item->cancellable,
(GAsyncReadyCallback)tunnel_handshake_complete,
tunnel_item);
+ g_object_unref (conn);
} else {
+ SoupConnection *conn = soup_message_get_connection (item->msg);
GError *error = NULL;
- soup_connection_tunnel_handshake (soup_message_get_connection (item->msg), item->cancellable, &error);
+ soup_connection_tunnel_handshake (conn, item->cancellable, &error);
+ g_object_unref (conn);
tunnel_complete (tunnel_item, SOUP_STATUS_OK, error);
}
}
@@ -1540,6 +1563,7 @@ tunnel_connect (SoupMessageQueueItem *item)
SoupSession *session = item->session;
SoupMessageQueueItem *tunnel_item;
SoupMessage *msg;
+ SoupConnection *conn;
item->state = SOUP_MESSAGE_TUNNELING;
@@ -1551,7 +1575,9 @@ tunnel_connect (SoupMessageQueueItem *item)
item->cancellable);
tunnel_item->io_priority = item->io_priority;
tunnel_item->related = soup_message_queue_item_ref (item);
- soup_message_set_connection (tunnel_item->msg, soup_message_get_connection (item->msg));
+ conn = soup_message_get_connection (item->msg);
+ soup_message_set_connection (tunnel_item->msg, conn);
+ g_clear_object (&conn);
tunnel_item->state = SOUP_MESSAGE_RUNNING;
soup_session_send_queue_item (session, tunnel_item,
@@ -1699,13 +1725,16 @@ soup_session_process_queue_item (SoupSession *session,
return;
break;
- case SOUP_MESSAGE_CONNECTED:
- if (soup_connection_is_tunnelled (soup_message_get_connection (item->msg)))
+ case SOUP_MESSAGE_CONNECTED: {
+ SoupConnection *conn = soup_message_get_connection (item->msg);
+
+ if (soup_connection_is_tunnelled (conn))
tunnel_connect (item);
else
item->state = SOUP_MESSAGE_READY;
+ g_object_unref (conn);
break;
-
+ }
case SOUP_MESSAGE_READY:
if (item->connect_only) {
item->state = SOUP_MESSAGE_FINISHING;