Re: [Evolution-hackers] [Fwd: [Fwd: A problem in libsoup]]



> What you described is pretty much the problem I was seeing.  As soon as
> the connection is made, connection_death() is set up.  Then the remote
> side immediately closes the connection.  This causes a HUP on the
> channel, and connection_death() loops forever because in_use is TRUE and
> is never set to FALSE.  Had the HUP occurred later, after the
> soup-transfer stuff had been set up, it would have just gone through the
> normal error and the connection would be released (and in_use set to
> FALSE) in soup_message_cleanup().

Ah. OK, so the problem is that we need to differentiate "not in use",
"sort of in use" (in_use TRUE but no message queued), and "definitely in
use".

Does this work for you? (And JP, does it work for you?)

Index: soup-context.c
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-context.c,v
retrieving revision 1.47
diff -u -r1.47 soup-context.c
--- soup-context.c	7 Apr 2003 20:55:31 -0000	1.47
+++ soup-context.c	9 Apr 2003 16:46:13 -0000
@@ -271,6 +271,11 @@
 		  GIOCondition    condition,
 		  SoupConnection *conn)
 {
+	if ((condition & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) && !conn->message) {
+		/* Some error condition, drop the connection immediately */
+		conn->in_use = FALSE;
+	}
+
 	if (!conn->in_use) {
 		connection_free (conn);
 		return FALSE;
Index: soup-message.c
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-message.c,v
retrieving revision 1.53
diff -u -r1.53 soup-message.c
--- soup-message.c	31 Mar 2003 15:32:39 -0000	1.53
+++ soup-message.c	9 Apr 2003 16:46:14 -0000
@@ -180,7 +180,7 @@
 						  release_and_close_connection,
 						  req->connection);
 		req->priv->read_tag = 0;
-		req->connection = NULL;
+		soup_message_set_connection (req, NULL, FALSE);
 		/* 
 		 * The buffer doesn't belong to us until the message is 
 		 * finished.
@@ -204,8 +204,7 @@
 	}
 
 	if (req->connection) {
-		soup_connection_release (req->connection);
-		req->connection = NULL;
+		soup_message_set_connection (req, NULL, TRUE);
 	}
 
 	soup_queue_remove_request (req);
@@ -556,8 +555,7 @@
 	soup_context_ref (dest_ctx);
 
 	soup_connection_set_keep_alive (msg->connection, FALSE);
-	soup_connection_release (msg->connection);
-	msg->connection = NULL;
+	soup_message_set_connection (msg, NULL, TRUE);
 
 	soup_queue_message (msg, 
 			    msg->priv->callback, 
@@ -581,17 +579,16 @@
 	SoupMessage *msg = data->msg;
 	SoupConnection *conn = msg->connection;
 
-	if (!soup_connection_is_keep_alive (msg->connection))
+	if (!soup_connection_is_keep_alive (conn))
 		requeue_read_error (FALSE, data);
 	else {
 		g_free (data);
-		msg->connection = NULL;
-
+		soup_message_set_connection (msg, NULL, FALSE);
 		soup_queue_message (msg, 
 				    msg->priv->callback, 
 				    msg->priv->user_data);
 
-		msg->connection = conn;
+		soup_message_set_connection (msg, conn, FALSE);
 	}
 }
 
@@ -1206,6 +1203,21 @@
 		soup_context_ref (msg->context);
 
 	return msg->context;
+}
+
+void
+soup_message_set_connection (SoupMessage *msg, SoupConnection *conn,
+			     gboolean release_old)
+{
+	if (msg->connection) {
+		if (msg->connection->message == msg)
+			msg->connection->message = NULL;
+		if (release_old)
+			soup_connection_release (msg->connection);
+	}
+	msg->connection = conn;
+	if (conn)
+		conn->message = msg;
 }
 
 void
Index: soup-private.h
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-private.h,v
retrieving revision 1.53
diff -u -r1.53 soup-private.h
--- soup-private.h	15 Nov 2002 16:26:42 -0000	1.53
+++ soup-private.h	9 Apr 2003 16:46:14 -0000
@@ -74,6 +74,7 @@
 struct _SoupConnection {
 	SoupHost     *server;
 	SoupContext  *context;
+	SoupMessage  *message;
 	GIOChannel   *channel;
 	SoupSocket   *socket;
 	SoupAuth     *auth;
@@ -131,6 +132,10 @@
 				      SoupHandlerType   invoke_type);
 
 void     soup_message_cleanup        (SoupMessage      *req);
+
+void     soup_message_set_connection     (SoupMessage    *msg,
+					  SoupConnection *conn,
+					  gboolean        release_previous);
 
 /* from soup-misc.c */
 
Index: soup-queue.c
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-queue.c,v
retrieving revision 1.77
diff -u -r1.77 soup-queue.c
--- soup-queue.c	24 Mar 2003 15:39:02 -0000	1.77
+++ soup-queue.c	9 Apr 2003 16:46:14 -0000
@@ -529,7 +529,7 @@
 	/*
 	 * Avoid releasing the connection on message free
 	 */
-	msg->connection = NULL;
+	soup_message_set_connection (msg, NULL, FALSE);
 }
 
 static gboolean
@@ -548,7 +548,7 @@
 		return FALSE;
 
 	connect_msg = soup_message_new (dest_ctx, SOUP_METHOD_CONNECT);
-	connect_msg->connection = conn;
+	soup_message_set_connection (connect_msg, conn, FALSE);
 	soup_message_add_handler (connect_msg, 
 				  SOUP_HANDLER_POST_BODY,
 				  proxy_https_connect_cb,
@@ -610,7 +610,7 @@
 	SoupMessage *req = user_data;
 
 	req->priv->connect_tag = NULL;
-	req->connection = conn;
+	soup_message_set_connection (req, conn, TRUE);
 
 	switch (err) {
 	case SOUP_CONNECT_ERROR_NONE:


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