[libsoup] Fix some problems with cancelling an async socket connect op



commit fecc55438abff5746328fd447a81af2bd73dc2aa
Author: Dan Winship <danw gnome org>
Date:   Mon Apr 2 09:56:37 2012 -0400

    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.

 libsoup/soup-socket.c |   27 +++++++++++++++++++--------
 1 files changed, 19 insertions(+), 8 deletions(-)
---
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index 42f1fed..26c90c4 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);



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