[libsoup] Fix warnings/failures with messages that are cancelled from got-headers



commit e14d55e4eda0d6f5efd02af04b1a999121eb09b8
Author: Dan Winship <danw gnome org>
Date:   Wed May 2 10:32:57 2012 -0400

    Fix warnings/failures with messages that are cancelled from got-headers
    
    https://bugzilla.gnome.org/show_bug.cgi?id=674747

 libsoup/soup-message-io.c    |   24 +++++++++++++++++++-----
 libsoup/soup-session-async.c |   18 ++++++++++--------
 libsoup/soup-session-sync.c  |   25 +++++++++++++++++++++----
 3 files changed, 50 insertions(+), 17 deletions(-)
---
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index 713cd17..a2b6bb5 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -804,6 +804,7 @@ io_run_until (SoupMessage *msg,
 	SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
 	SoupMessageIOData *io = priv->io_data;
 	gboolean progress = TRUE, done;
+	GError *my_error = NULL;
 
 	if (g_cancellable_set_error_if_cancelled (cancellable, error))
 		return FALSE;
@@ -820,15 +821,28 @@ io_run_until (SoupMessage *msg,
 	       (io->read_state < read_state || io->write_state < write_state)) {
 
 		if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->read_state))
-			progress = io_read (msg, cancellable, error);
+			progress = io_read (msg, cancellable, &my_error);
 		else if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->write_state))
-			progress = io_write (msg, cancellable, error);
+			progress = io_write (msg, cancellable, &my_error);
 		else
 			progress = FALSE;
 	}
 
-	done = (priv->io_data == io &&
-		io->read_state >= read_state &&
+	if (my_error) {
+		g_propagate_error (error, my_error);
+		g_object_unref (msg);
+		return FALSE;
+	} else if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+		return FALSE;
+	} else if (priv->io_data != io) {
+		g_set_error_literal (error, G_IO_ERROR,
+				     G_IO_ERROR_CANCELLED,
+				     _("Operation was cancelled"));
+		g_object_unref (msg);
+		return FALSE;
+	}
+
+	done = (io->read_state >= read_state &&
 		io->write_state >= write_state);
 
 	g_object_unref (msg);
@@ -859,7 +873,7 @@ io_run (SoupMessage *msg, gpointer user_data)
 		g_clear_error (&error);
 		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) {
+	} else if (error && priv->io_data == io) {
 		io_error (msg, error);
 	}
 
diff --git a/libsoup/soup-session-async.c b/libsoup/soup-session-async.c
index ea2820a..0f3aeff 100644
--- a/libsoup/soup-session-async.c
+++ b/libsoup/soup-session-async.c
@@ -569,6 +569,7 @@ send_request_finished (SoupSession *session, SoupMessageQueueItem *item)
 {
 	GMemoryOutputStream *mostream;
 	GInputStream *istream = NULL;
+	GError *error = NULL;
 
 	if (!item->result) {
 		/* Something else already took care of it. */
@@ -576,7 +577,7 @@ send_request_finished (SoupSession *session, SoupMessageQueueItem *item)
 	}
 
 	mostream = g_object_get_data (G_OBJECT (item->msg), "SoupSessionAsync:ostream");
-	if (mostream && !SOUP_STATUS_IS_TRANSPORT_ERROR (item->msg->status_code)) {
+	if (mostream) {
 		gpointer data;
 		gssize size;
 
@@ -586,9 +587,16 @@ send_request_finished (SoupSession *session, SoupMessageQueueItem *item)
 		size = g_memory_output_stream_get_data_size (mostream);
 		data = size ? g_memory_output_stream_steal_data (mostream) : g_strdup ("");
 		istream = g_memory_input_stream_new_from_data (data, size, g_free);
+	} else {
+		/* The message finished before becoming readable. This
+		 * will happen, eg, if it's cancelled from got-headers.
+		 * Do nothing; the op will complete via read_ready_cb()
+		 * after we return;
+		 */
+		return;
 	}
 
-	send_request_return_result (item, istream, NULL);
+	send_request_return_result (item, istream, error);
 }
 
 static void
@@ -660,12 +668,6 @@ static gboolean
 read_ready_cb (SoupMessage *msg, gpointer user_data)
 {
 	SoupMessageQueueItem *item = user_data;
-	GError *error = NULL;
-
-	if (g_cancellable_set_error_if_cancelled (item->cancellable, &error)) {
-		send_request_return_result (item, NULL, error);
-		return FALSE;
-	}
 
 	try_run_until_read (item);
 	return FALSE;
diff --git a/libsoup/soup-session-sync.c b/libsoup/soup-session-sync.c
index 039779a..3bdb347 100644
--- a/libsoup/soup-session-sync.c
+++ b/libsoup/soup-session-sync.c
@@ -485,6 +485,7 @@ soup_session_send_request (SoupSession   *session,
 	GOutputStream *ostream;
 	GMemoryOutputStream *mostream;
 	gssize size;
+	GError *my_error = NULL;
 
 	g_return_val_if_fail (SOUP_IS_SESSION_SYNC (session), NULL);
 
@@ -494,6 +495,10 @@ soup_session_send_request (SoupSession   *session,
 	g_return_val_if_fail (item != NULL, NULL);
 
 	item->new_api = TRUE;
+	if (cancellable) {
+		g_object_unref (item->cancellable);
+		item->cancellable = g_object_ref (cancellable);
+	}
 
 	while (!stream) {
 		/* Get a connection, etc */
@@ -502,10 +507,10 @@ soup_session_send_request (SoupSession   *session,
 			break;
 
 		/* Send request, read headers */
-		if (!soup_message_io_run_until_read (msg, cancellable, error))
+		if (!soup_message_io_run_until_read (msg, item->cancellable, &my_error))
 			break;
 
-		stream = soup_message_io_get_response_istream (msg, error);
+		stream = soup_message_io_get_response_istream (msg, &my_error);
 		if (!stream)
 			break;
 
@@ -520,7 +525,7 @@ soup_session_send_request (SoupSession   *session,
 		if (g_output_stream_splice (ostream, stream,
 					    G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
 					    G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
-					    cancellable, error) == -1) {
+					    item->cancellable, &my_error) == -1) {
 			g_object_unref (stream);
 			g_object_unref (ostream);
 			stream = NULL;
@@ -547,7 +552,9 @@ soup_session_send_request (SoupSession   *session,
 		g_object_unref (ostream);
 	}
 
-	if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) {
+	if (my_error)
+		g_propagate_error (error, my_error);
+	else if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) {
 		if (stream) {
 			g_object_unref (stream);
 			stream = NULL;
@@ -556,6 +563,16 @@ soup_session_send_request (SoupSession   *session,
 				     msg->reason_phrase);
 	}
 
+	if (!stream) {
+		if (soup_message_io_in_progress (msg))
+			soup_message_io_finished (msg);
+		else if (item->state != SOUP_MESSAGE_FINISHED)
+			item->state = SOUP_MESSAGE_FINISHING;
+
+		if (item->state != SOUP_MESSAGE_FINISHED)
+			process_queue_item (item);
+	}
+
 	soup_message_queue_item_unref (item);
 	return stream;
 }



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