diff options
author | Dan Winship <danw@gnome.org> | 2012-07-13 15:27:13 -0400 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2012-07-13 15:27:13 -0400 |
commit | da4f5b9e2b83771b23dbcfde62499425fe066e93 (patch) | |
tree | 24e55085e454578604b03cf25476f986cd1cb021 /libsoup/soup-client-input-stream.c | |
parent | d9db0727ff48f96f5312e65c8f0296f634d2c2b4 (diff) | |
download | libsoup-da4f5b9e2b83771b23dbcfde62499425fe066e93.tar.gz |
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.
Diffstat (limited to 'libsoup/soup-client-input-stream.c')
-rw-r--r-- | 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 a22c6854..5c18eaa0 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 |