[libsoup] Move SoupSocket stuff out of soup-message-io.c



commit bac8c22fd28479a3be149c0d742b8c7417381091
Author: Dan Winship <danw gnome org>
Date:   Fri Apr 20 11:29:14 2012 -0400

    Move SoupSocket stuff out of soup-message-io.c
    
    Add a new SoupIOStream, which wraps the SoupFilterInputStream and
    GOutputStream that SoupSocket exposes. Pass that to soup-message-io
    rather than the SoupSocket, and update various other things for this.

 libsoup/Makefile.am              |    2 +
 libsoup/soup-connection.c        |    6 +-
 libsoup/soup-io-stream.c         |  205 ++++++++++++++++++++++++++++++++++++++
 libsoup/soup-io-stream.h         |   40 ++++++++
 libsoup/soup-message-client-io.c |   15 +++-
 libsoup/soup-message-io.c        |   65 +++++--------
 libsoup/soup-message-private.h   |    5 +-
 libsoup/soup-message-server-io.c |   16 +++-
 libsoup/soup-misc-private.h      |    7 +-
 libsoup/soup-socket.c            |   69 ++++++--------
 10 files changed, 340 insertions(+), 90 deletions(-)
---
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index 8fd8ee5..ddd4b13 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -123,6 +123,8 @@ libsoup_2_4_la_SOURCES =		\
 	soup-filter-input-stream.h	\
 	soup-form.c			\
 	soup-headers.c			\
+	soup-io-stream.h		\
+	soup-io-stream.c		\
 	soup-logger.c			\
 	soup-marshal.h			\
 	soup-marshal.c			\
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index ad4e8e6..fffa954 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -448,7 +448,7 @@ set_current_item (SoupConnection *conn, SoupMessageQueueItem *item)
 	if (item->msg->method == SOUP_METHOD_CONNECT) {
 		g_signal_emit (conn, signals[EVENT], 0,
 			       G_SOCKET_CLIENT_PROXY_NEGOTIATING,
-			       soup_socket_get_iostream (priv->socket));
+			       soup_socket_get_connection (priv->socket));
 	} else if (priv->state == SOUP_CONNECTION_IDLE)
 		soup_connection_set_state (conn, SOUP_CONNECTION_IN_USE);
 
@@ -478,7 +478,7 @@ clear_current_item (SoupConnection *conn)
 		    SOUP_STATUS_IS_SUCCESSFUL (item->msg->status_code)) {
 			g_signal_emit (conn, signals[EVENT], 0,
 				       G_SOCKET_CLIENT_PROXY_NEGOTIATED,
-				       soup_socket_get_iostream (priv->socket));
+				       soup_socket_get_connection (priv->socket));
 
 			/* We're now effectively no longer proxying */
 			soup_uri_free (priv->proxy_uri);
@@ -500,7 +500,7 @@ soup_connection_event (SoupConnection      *conn,
 	SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);
 
 	if (!connection && priv->socket)
-		connection = soup_socket_get_iostream (priv->socket);
+		connection = soup_socket_get_connection (priv->socket);
 
 	g_signal_emit (conn, signals[EVENT], 0,
 		       event, connection);
diff --git a/libsoup/soup-io-stream.c b/libsoup/soup-io-stream.c
new file mode 100644
index 0000000..7c114a9
--- /dev/null
+++ b/libsoup/soup-io-stream.c
@@ -0,0 +1,205 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-io-stream.c
+ *
+ * Copyright 2012 Red Hat, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gio/gio.h>
+
+#include "soup-io-stream.h"
+#include "soup-filter-input-stream.h"
+
+struct _SoupIOStreamPrivate {
+	GIOStream *base_iostream;
+	gboolean close_on_dispose;
+
+	GInputStream *istream;
+	GOutputStream *ostream;
+	gboolean disposing;
+};
+
+enum {
+	PROP_0,
+
+	PROP_BASE_IOSTREAM,
+	PROP_CLOSE_ON_DISPOSE
+};
+
+G_DEFINE_TYPE (SoupIOStream, soup_io_stream, G_TYPE_IO_STREAM)
+
+static void
+soup_io_stream_init (SoupIOStream *stream)
+{
+	stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
+						    SOUP_TYPE_IO_STREAM,
+						    SoupIOStreamPrivate);
+}
+
+static void
+soup_io_stream_set_property (GObject *object, guint prop_id,
+			     const GValue *value, GParamSpec *pspec)
+{
+	SoupIOStream *siostream = SOUP_IO_STREAM (object);
+	GIOStream *io;
+
+	switch (prop_id) {
+	case PROP_BASE_IOSTREAM:
+		io = siostream->priv->base_iostream = g_value_dup_object (value);
+		if (io) {
+			siostream->priv->istream =
+				soup_filter_input_stream_new (g_io_stream_get_input_stream (io));
+			siostream->priv->ostream =
+				g_object_ref (g_io_stream_get_output_stream (io));
+		} else {
+			g_clear_object (&siostream->priv->istream);
+			g_clear_object (&siostream->priv->ostream);
+		}
+		break;
+	case PROP_CLOSE_ON_DISPOSE:
+		siostream->priv->close_on_dispose = g_value_get_boolean (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+soup_io_stream_get_property (GObject *object, guint prop_id,
+			     GValue *value, GParamSpec *pspec)
+{
+	SoupIOStream *siostream = SOUP_IO_STREAM (object);
+
+	switch (prop_id) {
+	case PROP_BASE_IOSTREAM:
+		g_value_set_object (value, siostream->priv->base_iostream);
+		break;
+	case PROP_CLOSE_ON_DISPOSE:
+		g_value_set_boolean (value, siostream->priv->close_on_dispose);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+soup_io_stream_dispose (GObject *object)
+{
+	SoupIOStream *siostream = SOUP_IO_STREAM (object);
+
+	siostream->priv->disposing = TRUE;
+
+	G_OBJECT_CLASS (soup_io_stream_parent_class)->dispose (object);
+}
+
+static void
+soup_io_stream_finalize (GObject *object)
+{
+	SoupIOStream *siostream = SOUP_IO_STREAM (object);
+
+	if (siostream->priv->base_iostream)
+		g_object_unref (siostream->priv->base_iostream);
+
+	G_OBJECT_CLASS (soup_io_stream_parent_class)->finalize (object);
+}
+
+static GInputStream *
+soup_io_stream_get_input_stream (GIOStream *stream)
+{
+	return SOUP_IO_STREAM (stream)->priv->istream;
+}
+
+static GOutputStream *
+soup_io_stream_get_output_stream (GIOStream *stream)
+{
+	return SOUP_IO_STREAM (stream)->priv->ostream;
+}
+
+
+static gboolean
+soup_io_stream_close (GIOStream     *stream,
+		      GCancellable  *cancellable,
+		      GError       **error)
+{
+	SoupIOStream *siostream = SOUP_IO_STREAM (stream);
+
+	if (siostream->priv->disposing &&
+	    !siostream->priv->close_on_dispose)
+		return TRUE;
+
+	return g_io_stream_close (siostream->priv->base_iostream,
+				  cancellable, error);
+}
+
+static void    
+soup_io_stream_close_async (GIOStream           *stream,
+			    int                  io_priority,
+			    GCancellable        *cancellable,
+			    GAsyncReadyCallback  callback,
+			    gpointer             user_data)
+{
+	g_io_stream_close_async (SOUP_IO_STREAM (stream)->priv->base_iostream,
+				 io_priority, cancellable, callback, user_data);
+}
+
+static gboolean
+soup_io_stream_close_finish (GIOStream     *stream,
+                             GAsyncResult  *result,
+			     GError       **error)
+{
+	return g_io_stream_close_finish (SOUP_IO_STREAM (stream)->priv->base_iostream,
+					 result, error);
+}
+
+static void
+soup_io_stream_class_init (SoupIOStreamClass *stream_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (stream_class);
+	GIOStreamClass *io_stream_class = G_IO_STREAM_CLASS (stream_class);
+
+	g_type_class_add_private (stream_class, sizeof (SoupIOStreamPrivate));
+
+	object_class->set_property = soup_io_stream_set_property;
+	object_class->get_property = soup_io_stream_get_property;
+	object_class->dispose = soup_io_stream_dispose;
+	object_class->finalize = soup_io_stream_finalize;
+
+	io_stream_class->get_input_stream = soup_io_stream_get_input_stream;
+	io_stream_class->get_output_stream = soup_io_stream_get_output_stream;
+	io_stream_class->close_fn = soup_io_stream_close;
+	io_stream_class->close_async = soup_io_stream_close_async;
+	io_stream_class->close_finish = soup_io_stream_close_finish;
+
+	g_object_class_install_property (
+		object_class, PROP_BASE_IOSTREAM,
+		g_param_spec_object ("base-iostream",
+				     "Base IOStream",
+				     "Base GIOStream",
+				     G_TYPE_IO_STREAM,
+				     G_PARAM_READWRITE |
+				     G_PARAM_CONSTRUCT_ONLY));
+	g_object_class_install_property (
+		object_class, PROP_CLOSE_ON_DISPOSE,
+		g_param_spec_boolean ("close-on-dispose",
+				      "Close base stream",
+				      "Close base GIOStream when closing",
+				      TRUE,
+				      G_PARAM_READWRITE |
+				      G_PARAM_CONSTRUCT_ONLY));
+}
+
+GIOStream *
+soup_io_stream_new (GIOStream *base_iostream,
+		    gboolean   close_on_dispose)
+{
+	return g_object_new (SOUP_TYPE_IO_STREAM,
+			     "base-iostream", base_iostream,
+			     "close-on-dispose", close_on_dispose,
+			     NULL);
+}
diff --git a/libsoup/soup-io-stream.h b/libsoup/soup-io-stream.h
new file mode 100644
index 0000000..92c24c3
--- /dev/null
+++ b/libsoup/soup-io-stream.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright 2012 Red Hat, Inc.
+ */
+
+#ifndef __SOUP_IO_STREAM_H__
+#define __SOUP_IO_STREAM_H__ 1
+
+#include <libsoup/soup-types.h>
+
+G_BEGIN_DECLS
+
+#define SOUP_TYPE_IO_STREAM            (soup_io_stream_get_type ())
+#define SOUP_IO_STREAM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SOUP_TYPE_IO_STREAM, SoupIOStream))
+#define SOUP_IO_STREAM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_IO_STREAM, SoupIOStreamClass))
+#define SOUP_IS_IO_STREAM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SOUP_TYPE_IO_STREAM))
+#define SOUP_IS_IO_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SOUP_TYPE_IO_STREAM))
+#define SOUP_IO_STREAM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_IO_STREAM, SoupIOStreamClass))
+
+typedef struct _SoupIOStreamPrivate SoupIOStreamPrivate;
+
+typedef struct {
+	GIOStream parent;
+
+	SoupIOStreamPrivate *priv;
+} SoupIOStream;
+
+typedef struct {
+	GIOStreamClass parent_class;
+
+} SoupIOStreamClass;
+
+GType soup_io_stream_get_type (void);
+
+GIOStream *soup_io_stream_new (GIOStream *base_iostream,
+			       gboolean   close_on_dispose);
+
+G_END_DECLS
+
+#endif /* __SOUP_IO_STREAM_H__ */
diff --git a/libsoup/soup-message-client-io.c b/libsoup/soup-message-client-io.c
index 8796e90..f6c752f 100644
--- a/libsoup/soup-message-client-io.c
+++ b/libsoup/soup-message-client-io.c
@@ -18,6 +18,8 @@
 #include "soup-connection.h"
 #include "soup-headers.h"
 #include "soup-message-queue.h"
+#include "soup-misc-private.h"
+#include "soup-session-async.h"
 #include "soup-uri.h"
 
 static guint
@@ -142,8 +144,19 @@ soup_message_send_request (SoupMessageQueueItem      *item,
 			   SoupMessageCompletionFn    completion_cb,
 			   gpointer                   user_data)
 {
+	GMainContext *async_context;
+	GIOStream *iostream;
+
+	if (SOUP_IS_SESSION_ASYNC (item->session)) {
+		async_context = soup_session_get_async_context (item->session);
+		if (!async_context)
+			async_context = g_main_context_default ();
+	} else
+		async_context = NULL;
+	iostream = soup_socket_get_iostream (soup_connection_get_socket (item->conn));
+
 	soup_message_cleanup_response (item->msg);
-	soup_message_io_client (item,
+	soup_message_io_client (item, iostream, async_context,
 				get_request_headers,
 				parse_response_headers,
 				item,
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index cfb0688..713cd17 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -26,7 +26,6 @@
 #include "soup-message-queue.h"
 #include "soup-misc.h"
 #include "soup-misc-private.h"
-#include "soup-socket.h"
 
 typedef enum {
 	SOUP_MESSAGE_IO_CLIENT,
@@ -59,7 +58,7 @@ typedef struct {
 	SoupMessageIOMode     mode;
 	GCancellable         *cancellable;
 
-	SoupSocket             *sock;
+	GIOStream              *iostream;
 	SoupFilterInputStream  *istream;
 	GInputStream           *body_istream;
 	GOutputStream          *ostream;
@@ -109,12 +108,8 @@ soup_message_io_cleanup (SoupMessage *msg)
 		return;
 	priv->io_data = NULL;
 
-	if (io->sock)
-		g_object_unref (io->sock);
-	if (io->istream)
-		g_object_remove_weak_pointer (G_OBJECT (io->istream), (gpointer *)&io->istream);
-	if (io->ostream)
-		g_object_remove_weak_pointer (G_OBJECT (io->ostream), (gpointer *)&io->ostream);
+	if (io->iostream)
+		g_object_unref (io->iostream);
 	if (io->body_istream)
 		g_object_unref (io->body_istream);
 	if (io->body_ostream)
@@ -155,7 +150,7 @@ soup_message_io_stop (SoupMessage *msg)
 	}
 
 	if (io->read_state < SOUP_MESSAGE_IO_STATE_FINISHING)
-		soup_socket_disconnect (io->sock);
+		g_io_stream_close (io->iostream, NULL, NULL);
 }
 
 void
@@ -181,7 +176,7 @@ request_is_idempotent (SoupMessage *msg)
 }
 
 static void
-io_error (SoupSocket *sock, SoupMessage *msg, GError *error)
+io_error (SoupMessage *msg, GError *error)
 {
 	SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
 	SoupMessageIOData *io = priv->io_data;
@@ -865,7 +860,7 @@ io_run (SoupMessage *msg, gpointer user_data)
 		io->io_source = soup_message_io_get_source (msg, NULL, io_run, msg);
 		g_source_attach (io->io_source, io->async_context);
 	} else if (error) {
-		io_error (io->sock, msg, error);
+		io_error (msg, error);
 	}
 
 	g_object_unref (msg);
@@ -946,7 +941,8 @@ soup_message_io_get_response_istream (SoupMessage  *msg,
 
 
 static SoupMessageIOData *
-new_iostate (SoupMessage *msg, SoupSocket *sock, SoupMessageIOMode mode,
+new_iostate (SoupMessage *msg, GIOStream *iostream,
+	     GMainContext *async_context, SoupMessageIOMode mode,
 	     SoupMessageGetHeadersFn get_headers_cb,
 	     SoupMessageParseHeadersFn parse_headers_cb,
 	     gpointer header_data,
@@ -955,7 +951,6 @@ new_iostate (SoupMessage *msg, SoupSocket *sock, SoupMessageIOMode mode,
 {
 	SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
 	SoupMessageIOData *io;
-	gboolean non_blocking, use_thread_context;
 
 	io = g_slice_new0 (SoupMessageIOData);
 	io->mode = mode;
@@ -965,29 +960,15 @@ new_iostate (SoupMessage *msg, SoupSocket *sock, SoupMessageIOMode mode,
 	io->completion_cb    = completion_cb;
 	io->completion_data  = completion_data;
 
-	io->sock = g_object_ref (sock);
-	io->istream = SOUP_FILTER_INPUT_STREAM (soup_socket_get_input_stream (sock));
-	if (io->istream)
-		g_object_add_weak_pointer (G_OBJECT (io->istream), (gpointer *)&io->istream);
-	io->ostream = soup_socket_get_output_stream (sock);
-	if (io->ostream)
-		g_object_add_weak_pointer (G_OBJECT (io->ostream), (gpointer *)&io->ostream);
-
-	g_object_get (io->sock,
-		      SOUP_SOCKET_FLAG_NONBLOCKING, &non_blocking,
-		      SOUP_SOCKET_USE_THREAD_CONTEXT, &use_thread_context,
-		      NULL);
-	io->blocking = !non_blocking;
-
-	if (use_thread_context) {
-		io->async_context = g_main_context_get_thread_default ();
-		if (io->async_context)
-			g_main_context_ref (io->async_context);
-	} else {
-		g_object_get (io->sock,
-			      SOUP_SOCKET_ASYNC_CONTEXT, &io->async_context,
-			      NULL);
-	}
+	io->iostream = g_object_ref (iostream);
+	io->istream = SOUP_FILTER_INPUT_STREAM (g_io_stream_get_input_stream (iostream));
+	io->ostream = g_io_stream_get_output_stream (iostream);
+
+	if (async_context) {
+		io->async_context = g_main_context_ref (async_context);
+		io->blocking = FALSE;
+	} else
+		io->blocking = TRUE;
 
 	io->read_header_buf = g_byte_array_new ();
 	io->write_buf       = g_string_new (NULL);
@@ -1003,6 +984,8 @@ new_iostate (SoupMessage *msg, SoupSocket *sock, SoupMessageIOMode mode,
 
 void
 soup_message_io_client (SoupMessageQueueItem *item,
+			GIOStream *iostream,
+			GMainContext *async_context,
 			SoupMessageGetHeadersFn get_headers_cb,
 			SoupMessageParseHeadersFn parse_headers_cb,
 			gpointer header_data,
@@ -1010,9 +993,9 @@ soup_message_io_client (SoupMessageQueueItem *item,
 			gpointer completion_data)
 {
 	SoupMessageIOData *io;
-	SoupSocket *sock = soup_connection_get_socket (item->conn);
 
-	io = new_iostate (item->msg, sock, SOUP_MESSAGE_IO_CLIENT,
+	io = new_iostate (item->msg, iostream, async_context,
+			  SOUP_MESSAGE_IO_CLIENT,
 			  get_headers_cb, parse_headers_cb, header_data,
 			  completion_cb, completion_data);
 
@@ -1029,7 +1012,8 @@ soup_message_io_client (SoupMessageQueueItem *item,
 }
 
 void
-soup_message_io_server (SoupMessage *msg, SoupSocket *sock,
+soup_message_io_server (SoupMessage *msg,
+			GIOStream *iostream, GMainContext *async_context,
 			SoupMessageGetHeadersFn get_headers_cb,
 			SoupMessageParseHeadersFn parse_headers_cb,
 			gpointer header_data,
@@ -1038,7 +1022,8 @@ soup_message_io_server (SoupMessage *msg, SoupSocket *sock,
 {
 	SoupMessageIOData *io;
 
-	io = new_iostate (msg, sock, SOUP_MESSAGE_IO_SERVER,
+	io = new_iostate (msg, iostream, async_context,
+			  SOUP_MESSAGE_IO_SERVER,
 			  get_headers_cb, parse_headers_cb, header_data,
 			  completion_cb, completion_data);
 
diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h
index 0d34833..69490e9 100644
--- a/libsoup/soup-message-private.h
+++ b/libsoup/soup-message-private.h
@@ -65,13 +65,16 @@ void soup_message_read_request (SoupMessage               *req,
 				gpointer                   user_data);
 
 void soup_message_io_client    (SoupMessageQueueItem      *item,
+				GIOStream                 *iostream,
+				GMainContext              *async_context,
 				SoupMessageGetHeadersFn    get_headers_cb,
 				SoupMessageParseHeadersFn  parse_headers_cb,
 				gpointer                   headers_data,
 				SoupMessageCompletionFn    completion_cb,
 				gpointer                   user_data);
 void soup_message_io_server    (SoupMessage               *msg,
-				SoupSocket                *sock,
+				GIOStream                 *iostream,
+				GMainContext              *async_context,
 				SoupMessageGetHeadersFn    get_headers_cb,
 				SoupMessageParseHeadersFn  parse_headers_cb,
 				gpointer                   headers_data,
diff --git a/libsoup/soup-message-server-io.c b/libsoup/soup-message-server-io.c
index 8b07ebf..c40ace8 100644
--- a/libsoup/soup-message-server-io.c
+++ b/libsoup/soup-message-server-io.c
@@ -16,6 +16,7 @@
 #include "soup-address.h"
 #include "soup-auth.h"
 #include "soup-headers.h"
+#include "soup-misc-private.h"
 #include "soup-multipart.h"
 #include "soup-server.h"
 #include "soup-socket.h"
@@ -248,9 +249,22 @@ soup_message_read_request (SoupMessage               *msg,
 			   SoupMessageCompletionFn    completion_cb,
 			   gpointer                   user_data)
 {
-	soup_message_io_server (msg, sock,
+	GMainContext *async_context;
+	GIOStream *iostream;
+
+	g_object_get (sock,
+		      SOUP_SOCKET_ASYNC_CONTEXT, &async_context,
+		      NULL);
+	if (!async_context)
+		async_context = g_main_context_ref (g_main_context_default ());
+
+	iostream = soup_socket_get_iostream (sock);
+
+	soup_message_io_server (msg, iostream, async_context,
 				get_response_headers,
 				parse_request_headers,
 				sock,
 				completion_cb, user_data);
+	if (async_context)
+		g_main_context_unref (async_context);
 }
diff --git a/libsoup/soup-misc-private.h b/libsoup/soup-misc-private.h
index 8836f5b..018d66a 100644
--- a/libsoup/soup-misc-private.h
+++ b/libsoup/soup-misc-private.h
@@ -18,9 +18,8 @@ void  soup_socket_handshake_async (SoupSocket         *sock,
 				   SoupSocketCallback  callback,
 				   gpointer            user_data);
 
-GSocket       *soup_socket_get_gsocket       (SoupSocket *sock);
-GIOStream     *soup_socket_get_iostream      (SoupSocket *sock);
-GInputStream  *soup_socket_get_input_stream  (SoupSocket *sock);
-GOutputStream *soup_socket_get_output_stream (SoupSocket *sock);
+GSocket   *soup_socket_get_gsocket    (SoupSocket *sock);
+GIOStream *soup_socket_get_connection (SoupSocket *sock);
+GIOStream *soup_socket_get_iostream   (SoupSocket *sock);
 
 #endif /* SOUP_URI_PRIVATE_H */
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index 2d72b38..1658d09 100644
--- a/libsoup/soup-socket.c
+++ b/libsoup/soup-socket.c
@@ -19,6 +19,7 @@
 #include "soup-socket.h"
 #include "soup-address.h"
 #include "soup-filter-input-stream.h"
+#include "soup-io-stream.h"
 #include "soup-marshal.h"
 #include "soup-misc.h"
 #include "soup-misc-private.h"
@@ -69,7 +70,7 @@ enum {
 
 typedef struct {
 	SoupAddress *local_addr, *remote_addr;
-	GIOStream *conn;
+	GIOStream *conn, *iostream;
 	GSocket *gsock;
 	GInputStream *istream;
 	GOutputStream *ostream;
@@ -119,17 +120,9 @@ disconnect_internal (SoupSocket *sock, gboolean close)
 {
 	SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
 
-	if (priv->gsock) {
-		if (close)
-			g_socket_close (priv->gsock, NULL);
-		g_object_unref (priv->gsock);
-		priv->gsock = NULL;
-	}
-	if (priv->conn) {
-		if (G_IS_TLS_CONNECTION (priv->conn))
-			g_signal_handlers_disconnect_by_func (priv->conn, soup_socket_peer_certificate_changed, sock);
-		g_clear_object (&priv->conn);
-	}
+	g_clear_object (&priv->gsock);
+	if (priv->conn && close)
+		g_io_stream_close (priv->conn, NULL, NULL);
 
 	if (priv->read_src) {
 		g_source_destroy (priv->read_src);
@@ -151,12 +144,14 @@ finalize (GObject *object)
 			g_warning ("Disposing socket %p during connect", object);
 		g_object_unref (priv->connect_cancel);
 	}
-	if (priv->conn) {
+	if (priv->gsock) {
 		if (priv->clean_dispose)
 			g_warning ("Disposing socket %p while still connected", object);
 		disconnect_internal (SOUP_SOCKET (object), TRUE);
 	}
 
+	g_clear_object (&priv->conn);
+	g_clear_object (&priv->iostream);
 	g_clear_object (&priv->istream);
 	g_clear_object (&priv->ostream);
 
@@ -517,10 +512,12 @@ finish_socket_setup (SoupSocketPrivate *priv)
 
 	if (!priv->conn)
 		priv->conn = (GIOStream *)g_socket_connection_factory_create_connection (priv->gsock);
+	if (!priv->iostream)
+		priv->iostream = soup_io_stream_new (priv->conn, FALSE);
 	if (!priv->istream)
-		priv->istream = soup_filter_input_stream_new (g_io_stream_get_input_stream (priv->conn));
+		priv->istream = g_object_ref (g_io_stream_get_input_stream (priv->iostream));
 	if (!priv->ostream)
-		priv->ostream = g_object_ref (g_io_stream_get_output_stream (priv->conn));
+		priv->ostream = g_object_ref (g_io_stream_get_output_stream (priv->iostream));
 
 	g_socket_set_timeout (priv->gsock, priv->timeout);
 }
@@ -843,13 +840,21 @@ soup_socket_get_gsocket (SoupSocket *sock)
 }
 
 GIOStream *
-soup_socket_get_iostream (SoupSocket *sock)
+soup_socket_get_connection (SoupSocket *sock)
 {
 	g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
 
 	return SOUP_SOCKET_GET_PRIVATE (sock)->conn;
 }
 
+GIOStream *
+soup_socket_get_iostream (SoupSocket *sock)
+{
+	g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
+
+	return SOUP_SOCKET_GET_PRIVATE (sock)->iostream;
+}
+
 static GSource *
 soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond,
 			  GPollableSourceFunc callback, gpointer user_data,
@@ -1086,13 +1091,13 @@ soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
 	g_signal_connect (priv->conn, "notify::peer-certificate",
 			  G_CALLBACK (soup_socket_peer_certificate_changed), sock);
 
-	if (priv->istream)
-		g_object_unref (priv->istream);
-	if (priv->ostream)
-		g_object_unref (priv->ostream);
+	g_clear_object (&priv->istream);
+	g_clear_object (&priv->ostream);
+	g_clear_object (&priv->iostream);
+	priv->iostream = soup_io_stream_new (priv->conn, FALSE);
+	priv->istream = g_object_ref (g_io_stream_get_input_stream (priv->iostream));
+	priv->ostream = g_object_ref (g_io_stream_get_output_stream (priv->iostream));
 
-	priv->istream = soup_filter_input_stream_new (g_io_stream_get_input_stream (priv->conn));
-	priv->ostream = g_object_ref (g_io_stream_get_output_stream (priv->conn));
 	return TRUE;
 }
 	
@@ -1204,7 +1209,7 @@ soup_socket_disconnect (SoupSocket *sock)
 		g_cancellable_cancel (priv->connect_cancel);
 		return;
 	} else if (g_mutex_trylock (&priv->iolock)) {
-		if (priv->conn)
+		if (priv->gsock)
 			disconnect_internal (sock, TRUE);
 		else
 			already_disconnected = TRUE;
@@ -1254,7 +1259,7 @@ soup_socket_is_connected (SoupSocket *sock)
 	g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
 	priv = SOUP_SOCKET_GET_PRIVATE (sock);
 
-	return priv->conn != NULL;
+	return priv->conn && !g_io_stream_is_closed (priv->conn);
 }
 
 /**
@@ -1323,22 +1328,6 @@ soup_socket_get_remote_address (SoupSocket *sock)
 	return priv->remote_addr;
 }
 
-GInputStream *
-soup_socket_get_input_stream (SoupSocket *sock)
-{
-	g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
-
-	return SOUP_SOCKET_GET_PRIVATE (sock)->istream;
-}
-
-GOutputStream *
-soup_socket_get_output_stream (SoupSocket *sock)
-{
-	g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
-
-	return SOUP_SOCKET_GET_PRIVATE (sock)->ostream;
-}
-
 
 static gboolean
 socket_read_watch (GObject *pollable, gpointer user_data)



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