[libsoup/carlosgc/thread-safe: 6/9] Use GWeakRef instead of g_object_add_weak_pointer()




commit 6bc0253e61bb7888eda1ca6ccb705db1f764cf55
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Wed Apr 20 12:32:28 2022 +0200

    Use GWeakRef instead of g_object_add_weak_pointer()
    
    GWeakRef is thread safe

 libsoup/auth/soup-connection-auth.c          |  17 ++--
 libsoup/auth/soup-tls-interaction.c          |  31 ++++---
 libsoup/http1/soup-client-message-io-http1.c |   5 +-
 libsoup/http2/soup-client-message-io-http2.c |  43 ++++++----
 libsoup/soup-connection-manager.c            |   9 +-
 libsoup/soup-logger.c                        |   7 +-
 libsoup/soup-message-queue-item.c            |   3 +-
 libsoup/soup-message.c                       | 118 +++++++++++++++++----------
 libsoup/soup-session.c                       |  49 ++++++++---
 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 7b5cf02d..bae27ecd 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;
@@ -1406,6 +1416,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);
@@ -1415,8 +1427,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 {
@@ -1756,8 +1771,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);
@@ -1855,8 +1869,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 cad51a51..344162af 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 984dfdd4..ad1959c1 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;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]