[libsoup] soup-message-io: keep cancellable alive for duration of io_run_until



commit dba687f01cfe5aad36c3df1b830b1e1d6ab4592d
Author: Dan Winship <danw gnome org>
Date:   Tue May 15 12:20:19 2012 -0400

    soup-message-io: keep cancellable alive for duration of io_run_until
    
    io_run() passes io->cancellable to io_run_until(), but io may be
    destroyed (and cancellable unreffed) before io_run_until() returns,
    causing it to eventually call g_cancellable_is_cancelled() on garbage.
    Fix by reffing it around the io_run_until() call (though really this
    is just another example of "SoupMessageIOData needs to be
    refcounted".)
    
    Tweak misc-test to test this case.
    
    Fixes crasher in rygel test case. Based on a patch from Ray Strode.
    https://bugzilla.gnome.org/show_bug.cgi?id=676038

 libsoup/soup-message-io.c |    6 +++++-
 tests/misc-test.c         |   18 +++++++++++++++++-
 2 files changed, 22 insertions(+), 2 deletions(-)
---
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index 455265e..7a554df 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -886,6 +886,7 @@ io_run (SoupMessage *msg, gpointer user_data)
 	SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
 	SoupMessageIOData *io = priv->io_data;
 	GError *error = NULL;
+	GCancellable *cancellable;
 
 	if (io->io_source) {
 		g_source_destroy (io->io_source);
@@ -894,11 +895,12 @@ io_run (SoupMessage *msg, gpointer user_data)
 	}
 
 	g_object_ref (msg);
+	cancellable = io->cancellable ? g_object_ref (io->cancellable) : NULL;
 
 	if (io_run_until (msg,
 			  SOUP_MESSAGE_IO_STATE_DONE,
 			  SOUP_MESSAGE_IO_STATE_DONE,
-			  io->cancellable, &error)) {
+			  cancellable, &error)) {
 		soup_message_io_finished (msg);
 	} else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
 		g_clear_error (&error);
@@ -909,6 +911,8 @@ io_run (SoupMessage *msg, gpointer user_data)
 	}
 
 	g_object_unref (msg);
+	g_clear_object (&cancellable);
+
 	return FALSE;
 }
 
diff --git a/tests/misc-test.c b/tests/misc-test.c
index 39d63d3..a2b9937 100644
--- a/tests/misc-test.c
+++ b/tests/misc-test.c
@@ -857,11 +857,20 @@ cancel_message_thread (gpointer msg)
 }
 
 static void
+set_done (SoupSession *session, SoupMessage *msg, gpointer user_data)
+{
+	gboolean *done = user_data;
+
+	*done = TRUE;
+}
+
+static void
 do_cancel_while_reading_test_for_session (SoupSession *session)
 {
 	SoupMessage *msg;
 	GThread *thread = NULL;
 	SoupURI *uri;
+	gboolean done = FALSE;
 
 	uri = soup_uri_new_with_base (base_uri, "/slow");
 	msg = soup_message_new_from_uri ("GET", uri);
@@ -875,7 +884,14 @@ do_cancel_while_reading_test_for_session (SoupSession *session)
 	else
 		thread = g_thread_new ("cancel_message_thread", cancel_message_thread, msg);
 
-	soup_session_send_message (session, msg);
+	/* We intentionally don't use soup_session_send_message() here,
+	 * because it holds an extra ref on the SoupMessageQueueItem
+	 * relative to soup_session_queue_message().
+	 */
+	g_object_ref (msg);
+	soup_session_queue_message (session, msg, set_done, &done);
+	while (!done)
+		g_main_context_iteration (NULL, TRUE);
 
 	if (msg->status_code != SOUP_STATUS_CANCELLED) {
 		debug_printf (1, "      FAILED: %d %s (expected Cancelled)\n",



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