[libsoup/gnome-3-6] soup-filter-input-stream: fix non-blocking behavior to not spin
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup/gnome-3-6] soup-filter-input-stream: fix non-blocking behavior to not spin
- Date: Thu, 10 Jan 2013 14:38:59 +0000 (UTC)
commit 41d7436bb302af2603dfbc619a4d4e3b4fa19c6a
Author: Dan Winship <danw gnome org>
Date: Wed Dec 12 17:16:40 2012 +0100
soup-filter-input-stream: fix non-blocking behavior to not spin
Just having a non-empty internal buffer isn't enough to guarantee we
can do a non-blocking read; if the caller is doing a read_until, we
might have some data in the buffer but still be waiting to find the
boundary. So track that. Based on a patch from Gustavo Noronha Silva.
libsoup/soup-filter-input-stream.c | 22 ++++++++++++++++++----
1 files changed, 18 insertions(+), 4 deletions(-)
---
diff --git a/libsoup/soup-filter-input-stream.c b/libsoup/soup-filter-input-stream.c
index f8c7251..3b76386 100644
--- a/libsoup/soup-filter-input-stream.c
+++ b/libsoup/soup-filter-input-stream.c
@@ -22,6 +22,7 @@
struct _SoupFilterInputStreamPrivate {
GByteArray *buf;
+ gboolean need_more;
};
static void soup_filter_input_stream_pollable_init (GPollableInputStreamInterface *pollable_interface, gpointer interface_data);
@@ -78,6 +79,7 @@ soup_filter_input_stream_read_fn (GInputStream *stream,
{
SoupFilterInputStream *fstream = SOUP_FILTER_INPUT_STREAM (stream);
+ fstream->priv->need_more = FALSE;
if (fstream->priv->buf) {
return read_from_buf (fstream, buffer, count);
} else {
@@ -92,7 +94,7 @@ soup_filter_input_stream_is_readable (GPollableInputStream *stream)
{
SoupFilterInputStream *fstream = SOUP_FILTER_INPUT_STREAM (stream);
- if (fstream->priv->buf)
+ if (fstream->priv->buf && !fstream->priv->need_more)
return TRUE;
else
return g_pollable_input_stream_is_readable (G_POLLABLE_INPUT_STREAM (G_FILTER_INPUT_STREAM (fstream)->base_stream));
@@ -106,6 +108,7 @@ soup_filter_input_stream_read_nonblocking (GPollableInputStream *stream,
{
SoupFilterInputStream *fstream = SOUP_FILTER_INPUT_STREAM (stream);
+ fstream->priv->need_more = FALSE;
if (fstream->priv->buf) {
return read_from_buf (fstream, buffer, count);
} else {
@@ -122,7 +125,7 @@ soup_filter_input_stream_create_source (GPollableInputStream *stream,
SoupFilterInputStream *fstream = SOUP_FILTER_INPUT_STREAM (stream);
GSource *base_source, *pollable_source;
- if (fstream->priv->buf)
+ if (fstream->priv->buf && !fstream->priv->need_more)
base_source = g_timeout_source_new (0);
else
base_source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (G_FILTER_INPUT_STREAM (fstream)->base_stream), cancellable);
@@ -196,11 +199,13 @@ soup_filter_input_stream_read_until (SoupFilterInputStream *fstream,
gssize nread;
guint8 *p, *buf, *end;
gboolean eof = FALSE;
+ GError *my_error = NULL;
g_return_val_if_fail (SOUP_IS_FILTER_INPUT_STREAM (fstream), -1);
g_return_val_if_fail (!include_boundary || (boundary_length < length), -1);
*got_boundary = FALSE;
+ fstream->priv->need_more = FALSE;
if (!fstream->priv->buf || fstream->priv->buf->len < boundary_length) {
guint prev_len;
@@ -215,7 +220,7 @@ soup_filter_input_stream_read_until (SoupFilterInputStream *fstream,
nread = g_pollable_stream_read (G_FILTER_INPUT_STREAM (fstream)->base_stream,
buf + prev_len, length - prev_len,
blocking,
- cancellable, error);
+ cancellable, &my_error);
if (nread <= 0) {
if (prev_len)
fstream->priv->buf->len = prev_len;
@@ -226,8 +231,17 @@ soup_filter_input_stream_read_until (SoupFilterInputStream *fstream,
if (nread == 0 && prev_len)
eof = TRUE;
- else
+ else {
+ if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
+ fstream->priv->need_more = TRUE;
+ if (my_error)
+ g_propagate_error (error, my_error);
+
return nread;
+ }
+
+ if (my_error)
+ g_propagate_error (error, my_error);
} else
fstream->priv->buf->len = prev_len + nread;
} else
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]