diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2022-04-20 12:32:28 +0200 |
---|---|---|
committer | Carlos Garcia Campos <cgarcia@igalia.com> | 2022-06-08 12:36:17 +0200 |
commit | 2479d9f7ea17a4f8311e3fc73c6dffa3e59349c4 (patch) | |
tree | f0b4f1bb526225990183790d7f58034d70859266 | |
parent | 05d07ee44f69cf93d1abb98d88aa7688b4cb6fdb (diff) | |
download | libsoup-2479d9f7ea17a4f8311e3fc73c6dffa3e59349c4.tar.gz |
Use GWeakRef instead of g_object_add_weak_pointer()
GWeakRef is thread safe
-rw-r--r-- | libsoup/auth/soup-connection-auth.c | 17 | ||||
-rw-r--r-- | libsoup/auth/soup-tls-interaction.c | 31 | ||||
-rw-r--r-- | libsoup/http1/soup-client-message-io-http1.c | 5 | ||||
-rw-r--r-- | libsoup/http2/soup-client-message-io-http2.c | 43 | ||||
-rw-r--r-- | libsoup/soup-connection-manager.c | 9 | ||||
-rw-r--r-- | libsoup/soup-logger.c | 7 | ||||
-rw-r--r-- | libsoup/soup-message-queue-item.c | 3 | ||||
-rw-r--r-- | libsoup/soup-message.c | 118 | ||||
-rw-r--r-- | 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 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; |