[libsoup] SoupConnection: hide a special case



commit 6d15cbe99d93a6c6284cc9a571a4aaab52d422b9
Author: Dan Winship <danw gnome org>
Date:   Fri Sep 28 17:44:54 2012 -0400

    SoupConnection: hide a special case
    
    Previously SoupConnection required SoupSession to request that the
    connection's state be changed from IN_USE to IDLE after a CONNECT,
    even though this would not actually result in the connection's state
    changing, and even though SoupSession would have broken if the state
    had changed. Fix this up so that SoupSession can just leave the
    connection IN_USE in this case, and SoupConnection deals with fixing
    up its internal state accordingly.

 libsoup/soup-connection.c |   53 +++++++++++++++++++++++----------------------
 libsoup/soup-session.c    |    4 ++-
 2 files changed, 30 insertions(+), 27 deletions(-)
---
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 783ab59..2cdcc30 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -380,18 +380,35 @@ current_msg_got_body (SoupMessage *msg, gpointer user_data)
 }
 
 static void
+clear_current_msg (SoupConnection *conn)
+{
+	SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);
+	SoupMessage *msg;
+
+	msg = priv->current_msg;
+	priv->current_msg = NULL;
+
+	g_signal_handlers_disconnect_by_func (msg, G_CALLBACK (current_msg_got_body), conn);
+	g_object_unref (msg);
+}
+
+static void
 set_current_msg (SoupConnection *conn, SoupMessage *msg)
 {
 	SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);
 
-	g_return_if_fail (priv->current_msg == NULL);
 	g_return_if_fail (priv->state == SOUP_CONNECTION_IN_USE);
 
 	g_object_freeze_notify (G_OBJECT (conn));
 
+	if (priv->current_msg) {
+		g_return_if_fail (priv->current_msg->method == SOUP_METHOD_CONNECT);
+		clear_current_msg (conn);
+	}
+
 	stop_idle_timer (priv);
 
-	priv->current_msg = msg;
+	priv->current_msg = g_object_ref (msg);
 	priv->reusable = FALSE;
 
 	g_signal_connect (msg, "got-body",
@@ -869,7 +886,6 @@ void
 soup_connection_set_state (SoupConnection *conn, SoupConnectionState state)
 {
 	SoupConnectionPrivate *priv;
-	SoupConnectionState old_state;
 
 	g_return_if_fail (SOUP_IS_CONNECTION (conn));
 	g_return_if_fail (state >= SOUP_CONNECTION_NEW &&
@@ -878,36 +894,20 @@ soup_connection_set_state (SoupConnection *conn, SoupConnectionState state)
 	g_object_freeze_notify (G_OBJECT (conn));
 
 	priv = SOUP_CONNECTION_GET_PRIVATE (conn);
-	old_state = priv->state;
-
-	if (old_state == SOUP_CONNECTION_IN_USE)
-		priv->unused_timeout = 0;
 
 	if (priv->current_msg) {
-		SoupMessage *msg;
-
 		g_warn_if_fail (state == SOUP_CONNECTION_IDLE ||
 				state == SOUP_CONNECTION_DISCONNECTED);
-
-		msg = priv->current_msg;
-		priv->current_msg = NULL;
-
-		g_signal_handlers_disconnect_by_func (msg, G_CALLBACK (current_msg_got_body), conn);
-
-		if (msg->method == SOUP_METHOD_CONNECT &&
-		    SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
-			if (state == SOUP_CONNECTION_IDLE)
-				state = SOUP_CONNECTION_IN_USE;
-		}
-
-		if (!priv->reusable)
-			soup_connection_disconnect (conn);
+		clear_current_msg (conn);
 	}
 
-	if (priv->state == old_state && priv->state != state) {
+	if (state == SOUP_CONNECTION_IDLE && !priv->reusable) {
+		/* This will recursively call set_state() */
+		soup_connection_disconnect (conn);
+	} else {
 		priv->state = state;
 
-		if (state == SOUP_CONNECTION_IDLE)
+		if (priv->state == SOUP_CONNECTION_IDLE)
 			start_idle_timer (conn);
 
 		g_object_notify (G_OBJECT (conn), "state");
@@ -941,7 +941,8 @@ soup_connection_send_request (SoupConnection          *conn,
 	g_return_if_fail (SOUP_IS_CONNECTION (conn));
 	g_return_if_fail (item != NULL);
 	priv = SOUP_CONNECTION_GET_PRIVATE (conn);
-	g_return_if_fail (priv->state != SOUP_CONNECTION_NEW && priv->state != SOUP_CONNECTION_DISCONNECTED);
+	g_return_if_fail (priv->state != SOUP_CONNECTION_NEW &&
+			  priv->state != SOUP_CONNECTION_DISCONNECTED);
 
 	if (item->msg != priv->current_msg)
 		set_current_msg (conn, item->msg);
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 5a3c5f9..fe51a40 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -1337,7 +1337,9 @@ soup_session_unqueue_item (SoupSession          *session,
 	SoupSessionHost *host;
 
 	if (item->conn) {
-		if (soup_connection_get_state (item->conn) == SOUP_CONNECTION_IN_USE)
+		if ((soup_connection_get_state (item->conn) == SOUP_CONNECTION_IN_USE) &&
+		    (item->msg->method != SOUP_METHOD_CONNECT ||
+		     !SOUP_STATUS_IS_SUCCESSFUL (item->msg->status_code)))
 			soup_connection_set_state (item->conn, SOUP_CONNECTION_IDLE);
 		soup_message_queue_item_set_connection (item, NULL);
 	}



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