summaryrefslogtreecommitdiff
path: root/libsoup/soup-socket.c
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2012-04-02 09:56:37 -0400
committerDan Winship <danw@gnome.org>2012-04-02 09:56:37 -0400
commitfecc55438abff5746328fd447a81af2bd73dc2aa (patch)
treeefbbeffff3c41e0da7aeba585c1f04f0f11ce7f3 /libsoup/soup-socket.c
parent0c0619228a3488a4808cad2383073e00db22cd6d (diff)
downloadlibsoup-fecc55438abff5746328fd447a81af2bd73dc2aa.tar.gz
Fix some problems with cancelling an async socket connect op
Cancelling a message while it was still connecting could result in an (erroneous) warning about "disposing socket while still connected", or an (accurate) warning about passing NULL to g_tls_connection_handshake_finish(). Fix both of these. Pointed out on the mailing list by Sven Neumann.
Diffstat (limited to 'libsoup/soup-socket.c')
-rw-r--r--libsoup/soup-socket.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index 42f1feda..26c90c44 100644
--- a/libsoup/soup-socket.c
+++ b/libsoup/soup-socket.c
@@ -115,12 +115,13 @@ soup_socket_init (SoupSocket *sock)
}
static void
-disconnect_internal (SoupSocket *sock)
+disconnect_internal (SoupSocket *sock, gboolean close)
{
SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
if (priv->gsock) {
- g_socket_close (priv->gsock, NULL);
+ if (close)
+ g_socket_close (priv->gsock, NULL);
g_object_unref (priv->gsock);
priv->gsock = NULL;
}
@@ -156,7 +157,7 @@ finalize (GObject *object)
if (priv->conn) {
if (priv->clean_dispose)
g_warning ("Disposing socket %p while still connected", object);
- disconnect_internal (SOUP_SOCKET (object));
+ disconnect_internal (SOUP_SOCKET (object), TRUE);
}
if (priv->local_addr)
@@ -671,8 +672,14 @@ socket_connected (SoupSocket *sock, GSocketConnection *conn, GError *error)
{
SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
- g_object_unref (priv->connect_cancel);
- priv->connect_cancel = NULL;
+ if (priv->connect_cancel) {
+ GCancellable *cancellable = priv->connect_cancel;
+
+ g_object_unref (priv->connect_cancel);
+ priv->connect_cancel = NULL;
+ if (g_cancellable_is_cancelled (cancellable))
+ return SOUP_STATUS_CANCELLED;
+ }
if (error) {
if (error->domain == G_RESOLVER_ERROR) {
@@ -968,7 +975,7 @@ soup_socket_listen (SoupSocket *sock)
cant_listen:
if (priv->conn)
- disconnect_internal (sock);
+ disconnect_internal (sock, TRUE);
g_object_unref (addr);
return FALSE;
@@ -1031,6 +1038,9 @@ soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
if (G_IS_TLS_CONNECTION (priv->conn))
return TRUE;
+ if (g_cancellable_is_cancelled (cancellable))
+ return FALSE;
+
priv->ssl = TRUE;
if (!priv->is_server) {
@@ -1116,7 +1126,7 @@ handshake_async_ready (GObject *source, GAsyncResult *result, gpointer user_data
if (priv->async_context && !priv->use_thread_context)
g_main_context_pop_thread_default (priv->async_context);
- if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (priv->conn),
+ if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (source),
result, &error))
status = SOUP_STATUS_OK;
else if (!priv->ssl_fallback &&
@@ -1188,11 +1198,12 @@ soup_socket_disconnect (SoupSocket *sock)
priv = SOUP_SOCKET_GET_PRIVATE (sock);
if (priv->connect_cancel) {
+ disconnect_internal (sock, FALSE);
g_cancellable_cancel (priv->connect_cancel);
return;
} else if (g_mutex_trylock (&priv->iolock)) {
if (priv->conn)
- disconnect_internal (sock);
+ disconnect_internal (sock, TRUE);
else
already_disconnected = TRUE;
g_mutex_unlock (&priv->iolock);