summaryrefslogtreecommitdiff
path: root/libsoup
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2013-11-04 16:41:10 -0500
committerDan Winship <danw@gnome.org>2013-11-04 16:48:41 -0500
commit4e755ba87e2937ce32c53c2983d4efe8b9121541 (patch)
tree7dfb8b0289835219256fe084198315024cc83905 /libsoup
parentda167aad39438d4df33df189c97bd07e989d38d0 (diff)
downloadlibsoup-4e755ba87e2937ce32c53c2983d4efe8b9121541.tar.gz
Fix SoupClientInputStream close on error
g_input/output_stream_close() always mark their stream closed, even on error, even if their cancellable is pre-cancelled. That means we have to guarantee that soup_message_io_finished() gets called when a SoupClientInputStream is closed, even if an error occurs while closing. https://bugzilla.gnome.org/show_bug.cgi?id=711260
Diffstat (limited to 'libsoup')
-rw-r--r--libsoup/soup-client-input-stream.c9
-rw-r--r--libsoup/soup-message-io.c25
2 files changed, 21 insertions, 13 deletions
diff --git a/libsoup/soup-client-input-stream.c b/libsoup/soup-client-input-stream.c
index 87fa49d6..0264cb79 100644
--- a/libsoup/soup-client-input-stream.c
+++ b/libsoup/soup-client-input-stream.c
@@ -128,9 +128,12 @@ soup_client_input_stream_close_fn (GInputStream *stream,
GError **error)
{
SoupClientInputStream *cistream = SOUP_CLIENT_INPUT_STREAM (stream);
+ gboolean success;
- return soup_message_io_run_until_finish (cistream->priv->msg, TRUE,
- cancellable, error);
+ success = soup_message_io_run_until_finish (cistream->priv->msg, TRUE,
+ NULL, error);
+ soup_message_io_finished (cistream->priv->msg);
+ return success;
}
static gboolean
@@ -158,6 +161,8 @@ close_async_ready (SoupMessage *msg, gpointer user_data)
return TRUE;
}
+ soup_message_io_finished (cistream->priv->msg);
+
if (error) {
g_task_return_error (task, error);
g_object_unref (task);
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index 6ba29607..be5cb2d2 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -155,8 +155,14 @@ soup_message_io_finished (SoupMessage *msg)
{
SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
SoupMessageIOData *io = priv->io_data;
- SoupMessageCompletionFn completion_cb = io->completion_cb;
- gpointer completion_data = io->completion_data;
+ SoupMessageCompletionFn completion_cb;
+ gpointer completion_data;
+
+ if (!io)
+ return;
+
+ completion_cb = io->completion_cb;
+ completion_data = io->completion_data;
g_object_ref (msg);
soup_message_io_cleanup (msg);
@@ -984,6 +990,7 @@ soup_message_io_run_until_finish (SoupMessage *msg,
{
SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
SoupMessageIOData *io = priv->io_data;
+ gboolean success;
g_object_ref (msg);
@@ -994,17 +1001,13 @@ soup_message_io_run_until_finish (SoupMessage *msg,
io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
}
- if (!io_run_until (msg, blocking,
- SOUP_MESSAGE_IO_STATE_DONE,
- SOUP_MESSAGE_IO_STATE_DONE,
- cancellable, error)) {
- g_object_unref (msg);
- return FALSE;
- }
+ success = io_run_until (msg, blocking,
+ SOUP_MESSAGE_IO_STATE_DONE,
+ SOUP_MESSAGE_IO_STATE_DONE,
+ cancellable, error);
- soup_message_io_finished (msg);
g_object_unref (msg);
- return TRUE;
+ return success;
}
static void