[libsoup] soup-client-input-stream: don't chain up from close/close_async



commit da4f5b9e2b83771b23dbcfde62499425fe066e93
Author: Dan Winship <danw gnome org>
Date:   Fri Jul 13 15:27:13 2012 -0400

    soup-client-input-stream: don't chain up from close/close_async
    
    GInputStream's default close_async method runs the sync close method
    in a thread, which means that you can't chain up to it from a subclass
    implementation. And GFilterInputStream only overrides close_fn, not
    close_async, so there's no way to asynchronously get the
    close-base-stream behavior if we want to override close_async in
    SoupClientInputStream. Ugh! Anyway, we always have a non
    close-base-stream SoupBodyInputStream somewhere under the
    SoupClientInputStream, so there's no need to chain up anyway.
    
    Fixes a sporadic bug caused by the fact that we were closing the
    stream (and thus calling soup_message_io_run_until_finish()) twice.

 libsoup/soup-client-input-stream.c |   50 ++++++++++--------------------------
 1 files changed, 14 insertions(+), 36 deletions(-)
---
diff --git a/libsoup/soup-client-input-stream.c b/libsoup/soup-client-input-stream.c
index a22c685..5c18eaa 100644
--- a/libsoup/soup-client-input-stream.c
+++ b/libsoup/soup-client-input-stream.c
@@ -143,11 +143,8 @@ soup_client_input_stream_close_fn (GInputStream  *stream,
 {
 	SoupClientInputStream *cistream = SOUP_CLIENT_INPUT_STREAM (stream);
 
-	if (!soup_message_io_run_until_finish (cistream->priv->msg,
-					       cancellable, error))
-		return FALSE;
-
-	return G_INPUT_STREAM_CLASS (soup_client_input_stream_parent_class)->close_fn (stream, cancellable, error);
+	return soup_message_io_run_until_finish (cistream->priv->msg,
+						 cancellable, error);
 }
 
 typedef struct {
@@ -165,45 +162,26 @@ close_async_data_free (CloseAsyncData *cad)
 	g_slice_free (CloseAsyncData, cad);
 }
 
-static void
-base_stream_closed (GObject *source, GAsyncResult *result, gpointer user_data)
-{
-	CloseAsyncData *cad = user_data;
-	GError *error = NULL;
-
-	if (G_INPUT_STREAM_CLASS (soup_client_input_stream_parent_class)->
-	    close_finish (G_INPUT_STREAM (cad->cistream), result, &error))
-		g_simple_async_result_set_op_res_gboolean (cad->result, TRUE);
-	else
-		g_simple_async_result_take_error (cad->result, error);
-
-	g_simple_async_result_complete_in_idle (cad->result);
-	close_async_data_free (cad);
-}
-
 static gboolean
 close_async_ready (SoupMessage *msg, gpointer user_data)
 {
 	CloseAsyncData *cad = user_data;
 	GError *error = NULL;
 
-	if (soup_message_io_run_until_finish (cad->cistream->priv->msg,
-					      cad->cancellable, &error)) {
-		G_INPUT_STREAM_CLASS (soup_client_input_stream_parent_class)->
-			close_async (G_INPUT_STREAM (cad->cistream),
-				     cad->priority,
-				     cad->cancellable,
-				     base_stream_closed,
-				     cad);
-		return FALSE;
-	} else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
-		g_simple_async_result_take_error (cad->result, error);
-		g_simple_async_result_complete_in_idle (cad->result);
-		close_async_data_free (cad);
-		return FALSE;
+	if (!soup_message_io_run_until_finish (cad->cistream->priv->msg,
+					       cad->cancellable, &error) &&
+	    g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
+		g_error_free (error);
+		return TRUE;
 	}
 
-	return TRUE;
+	if (error)
+		g_simple_async_result_take_error (cad->result, error);
+	else
+		g_simple_async_result_set_op_res_gboolean (cad->result, TRUE);
+	g_simple_async_result_complete_in_idle (cad->result);
+	close_async_data_free (cad);
+	return FALSE;
 }
 
 static void



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