[libsoup] soup-socket: remove close-on-dispose



commit 019488c2bcffe70a62166406f39c7905027edb59
Author: Dan Winship <danw gnome org>
Date:   Mon Mar 2 20:34:55 2015 -0500

    soup-socket: remove close-on-dispose
    
    Setting close-on-dispose=FALSE on a socket would cause it to leak its
    GSocket. Indeed, there is no way to avoid this, since freeing the
    GSocket will always close it.
    
    Work around the problem in a different way by having the steal()
    methods steal the GSocket from the SoupSocket, and ensure that it gets
    freed later along with the stolen GIOStream.

 libsoup/soup-server.c         |    6 +++---
 libsoup/soup-session.c        |    8 +++++---
 libsoup/soup-socket-private.h |    2 +-
 libsoup/soup-socket.c         |   35 ++++++++++++++++++-----------------
 tests/socket-test.c           |    6 ------
 5 files changed, 27 insertions(+), 30 deletions(-)
---
diff --git a/libsoup/soup-server.c b/libsoup/soup-server.c
index fec9ceb..77b2142 100644
--- a/libsoup/soup-server.c
+++ b/libsoup/soup-server.c
@@ -2412,9 +2412,9 @@ soup_client_context_steal_connection (SoupClientContext *client)
 
        stream = soup_message_io_steal (client->msg);
        if (stream) {
-               g_object_set (G_OBJECT (client->sock),
-                             SOUP_SOCKET_CLOSE_ON_DISPOSE, FALSE,
-                             NULL);
+               g_object_set_data_full (G_OBJECT (stream), "GSocket",
+                                       soup_socket_steal_gsocket (client->sock),
+                                       g_object_unref);
        }
 
        socket_disconnected (client->sock, client);
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index a01aa95..6420183 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -4769,13 +4769,15 @@ soup_session_steal_connection (SoupSession *session,
        g_mutex_unlock (&priv->conn_lock);
 
        sock = soup_connection_get_socket (conn);
-       g_object_set (G_OBJECT (sock),
-                     SOUP_SOCKET_CLOSE_ON_DISPOSE, FALSE,
+       g_object_set (sock,
                      SOUP_SOCKET_TIMEOUT, 0,
                      NULL);
-       g_object_unref (conn);
 
        stream = soup_message_io_steal (item->msg);
+       g_object_set_data_full (G_OBJECT (stream), "GSocket",
+                               soup_socket_steal_gsocket (sock),
+                               g_object_unref);
+       g_object_unref (conn);
 
        soup_message_queue_item_unref (item);
        return stream;
diff --git a/libsoup/soup-socket-private.h b/libsoup/soup-socket-private.h
index 84fad04..c0bb7a1 100644
--- a/libsoup/soup-socket-private.h
+++ b/libsoup/soup-socket-private.h
@@ -9,7 +9,6 @@
 #include "soup-socket.h"
 
 #define SOUP_SOCKET_SOCKET_PROPERTIES "socket-properties"
-#define SOUP_SOCKET_CLOSE_ON_DISPOSE  "close-on-dispose"
 #define SOUP_SOCKET_FD                "fd"
 #define SOUP_SOCKET_GSOCKET           "gsocket"
 #define SOUP_SOCKET_IOSTREAM          "iostream"
@@ -41,6 +40,7 @@ gboolean   soup_socket_handshake_finish        (SoupSocket           *sock,
 
 gboolean   soup_socket_is_readable             (SoupSocket           *sock);
 GSocket   *soup_socket_get_gsocket             (SoupSocket           *sock);
+GSocket   *soup_socket_steal_gsocket           (SoupSocket           *sock);
 GIOStream *soup_socket_get_connection          (SoupSocket           *sock);
 GIOStream *soup_socket_get_iostream            (SoupSocket           *sock);
 
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index 90db59c..f10481b 100644
--- a/libsoup/soup-socket.c
+++ b/libsoup/soup-socket.c
@@ -67,7 +67,6 @@ enum {
        PROP_TRUSTED_CERTIFICATE,
        PROP_TLS_CERTIFICATE,
        PROP_TLS_ERRORS,
-       PROP_CLOSE_ON_DISPOSE,
        PROP_SOCKET_PROPERTIES,
 
        LAST_PROP
@@ -90,7 +89,6 @@ typedef struct {
        guint ssl_strict:1;
        guint ssl_fallback:1;
        guint clean_dispose:1;
-       guint close_on_dispose:1;
        guint use_thread_context:1;
        gpointer ssl_creds;
 
@@ -213,7 +211,7 @@ soup_socket_finalize (GObject *object)
                        g_warning ("Disposing socket %p during connect", object);
                g_object_unref (priv->connect_cancel);
        }
-       if (priv->conn && priv->close_on_dispose) {
+       if (priv->conn) {
                if (priv->clean_dispose)
                        g_warning ("Disposing socket %p while still connected", object);
                disconnect_internal (SOUP_SOCKET (object), TRUE);
@@ -363,9 +361,6 @@ soup_socket_set_property (GObject *object, guint prop_id,
                        priv->clean_dispose = TRUE;
                }
                break;
-       case PROP_CLOSE_ON_DISPOSE:
-               priv->close_on_dispose = g_value_get_boolean (value);
-               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -428,9 +423,6 @@ soup_socket_get_property (GObject *object, guint prop_id,
                g_value_set_flags (value, priv->tls_errors);
                break;
                break;
-       case PROP_CLOSE_ON_DISPOSE:
-               g_value_set_boolean (value, priv->close_on_dispose);
-               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -804,14 +796,6 @@ soup_socket_class_init (SoupSocketClass *socket_class)
                                     "Socket properties",
                                     SOUP_TYPE_SOCKET_PROPERTIES,
                                     G_PARAM_WRITABLE));
-
-       g_object_class_install_property (
-               object_class, PROP_CLOSE_ON_DISPOSE,
-               g_param_spec_boolean (SOUP_SOCKET_CLOSE_ON_DISPOSE,
-                                     "Close socket on disposal",
-                                     "Whether the socket is closed on disposal",
-                                     TRUE,
-                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 }
 
 static void
@@ -1139,6 +1123,23 @@ soup_socket_get_gsocket (SoupSocket *sock)
        return SOUP_SOCKET_GET_PRIVATE (sock)->gsock;
 }
 
+GSocket *
+soup_socket_steal_gsocket (SoupSocket *sock)
+{
+       SoupSocketPrivate *priv;
+       GSocket *gsock;
+
+       g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
+       priv = SOUP_SOCKET_GET_PRIVATE (sock);
+
+       gsock = priv->gsock;
+       priv->gsock = NULL;
+       g_clear_object (&priv->conn);
+       g_clear_object (&priv->iostream);
+
+       return gsock;
+}
+
 gboolean
 soup_socket_is_readable (SoupSocket *sock)
 {
diff --git a/tests/socket-test.c b/tests/socket-test.c
index cdeace2..52a8fbb 100644
--- a/tests/socket-test.c
+++ b/tests/socket-test.c
@@ -120,7 +120,6 @@ do_socket_from_fd_client_test (void)
        SoupAddress *local, *remote;
        GSocketAddress *gaddr;
        gboolean is_server;
-       int type;
        GError *error = NULL;
 
        server = soup_test_server_new (SOUP_TEST_SERVER_DEFAULT);
@@ -143,7 +142,6 @@ do_socket_from_fd_client_test (void)
 
        sock = g_initable_new (SOUP_TYPE_SOCKET, NULL, &error,
                               SOUP_SOCKET_FD, g_socket_get_fd (gsock),
-                              SOUP_SOCKET_CLOSE_ON_DISPOSE, FALSE,
                               NULL);
        g_assert_no_error (error);
        g_assert_nonnull (sock);
@@ -167,10 +165,6 @@ do_socket_from_fd_client_test (void)
        g_object_unref (gaddr);
 
        g_object_unref (sock);
-       /* We specified close-on-dispose=FALSE */
-       g_socket_get_option (gsock, SOL_SOCKET, SO_TYPE, &type, &error);
-       g_assert_no_error (error);
-
        g_object_unref (gsock);
 
        g_object_unref (server);


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