Commit 117de38f authored by Dan Winship's avatar Dan Winship Committed by Alexander Larsson

Make this take a GError and return a gboolean, and do the "outstanding

2007-11-30  Dan Winship  <danw@gnome.org>

	* ginputstream.c (g_input_stream_set_pending): Make this take a
	GError and return a gboolean, and do the "outstanding operation"
	check (and the "stream is already closed" check) itself.
	(g_input_stream_clear_pending): Formerly set_pending(FALSE).

	* goutputstream.c (g_output_stream_set_pending)
	(g_output_stream_clear_pending): Likewise

	* gbufferedinputstream.c: 
	* gfileinputstream.c: 
	* gfileoutputstream.c: Update for that

	* gsimpleasyncresult.c (g_simple_async_report_gerror_in_idle):
	Like g_simple_async_report_error_in_idle, but takes a GError
	rather than building one.


svn path=/trunk/; revision=6039
parent b22aa6dd
2007-11-30 Dan Winship <danw@gnome.org>
* ginputstream.c (g_input_stream_set_pending): Make this take a
GError and return a gboolean, and do the "outstanding operation"
check (and the "stream is already closed" check) itself.
(g_input_stream_clear_pending): Formerly set_pending(FALSE).
* goutputstream.c (g_output_stream_set_pending)
(g_output_stream_clear_pending): Likewise
* gbufferedinputstream.c:
* gfileinputstream.c:
* gfileoutputstream.c: Update for that
* gsimpleasyncresult.c (g_simple_async_report_gerror_in_idle):
Like g_simple_async_report_error_in_idle, but takes a GError
rather than building one.
2007-11-30 Dan Winship <danw@gnome.org>
* goutputstream.c: Don't cheat and unset the "pending" flag around
......
......@@ -405,21 +405,8 @@ g_buffered_input_stream_fill (GBufferedInputStream *stream,
input_stream = G_INPUT_STREAM (stream);
if (g_input_stream_is_closed (input_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return -1;
}
if (g_input_stream_has_pending (input_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
return -1;
}
g_input_stream_set_pending (input_stream, TRUE);
if (!g_input_stream_set_pending (input_stream, error))
return -1;
if (cancellable)
g_push_current_cancellable (cancellable);
......@@ -430,7 +417,7 @@ g_buffered_input_stream_fill (GBufferedInputStream *stream,
if (cancellable)
g_pop_current_cancellable (cancellable);
g_input_stream_set_pending (input_stream, FALSE);
g_input_stream_clear_pending (input_stream);
return res;
}
......@@ -442,7 +429,7 @@ async_fill_callback_wrapper (GObject *source_object,
{
GBufferedInputStream *stream = G_BUFFERED_INPUT_STREAM (source_object);
g_input_stream_set_pending (G_INPUT_STREAM (stream), FALSE);
g_input_stream_clear_pending (G_INPUT_STREAM (stream));
(*stream->priv->outstanding_callback) (source_object, res, user_data);
g_object_unref (stream);
}
......@@ -471,6 +458,7 @@ g_buffered_input_stream_fill_async (GBufferedInputStream *stream,
{
GBufferedInputStreamClass *class;
GSimpleAsyncResult *simple;
GError *error = NULL;
g_return_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream));
......@@ -495,29 +483,18 @@ g_buffered_input_stream_fill_async (GBufferedInputStream *stream,
return;
}
if (g_input_stream_is_closed (G_INPUT_STREAM (stream)))
if (!g_input_stream_set_pending (G_INPUT_STREAM (stream), &error))
{
g_simple_async_report_error_in_idle (G_OBJECT (stream),
callback,
user_data,
G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
callback,
user_data,
error);
g_error_free (error);
return;
}
if (g_input_stream_has_pending (G_INPUT_STREAM (stream)))
{
g_simple_async_report_error_in_idle (G_OBJECT (stream),
callback,
user_data,
G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
return;
}
class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
g_input_stream_set_pending (G_INPUT_STREAM (stream), TRUE);
stream->priv->outstanding_callback = callback;
g_object_ref (stream);
class->fill_async (stream, count, io_priority, cancellable,
......@@ -892,22 +869,19 @@ g_buffered_input_stream_read_byte (GBufferedInputStream *stream,
return -1;
}
if (g_input_stream_has_pending (input_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
return -1;
}
if (!g_input_stream_set_pending (input_stream, error))
return -1;
available = priv->end - priv->pos;
if (available < 1)
return priv->buffer[priv->pos++];
{
g_input_stream_clear_pending (input_stream);
return priv->buffer[priv->pos++];
}
/* Byte not available, request refill for more */
g_input_stream_set_pending (input_stream, TRUE);
if (cancellable)
g_push_current_cancellable (cancellable);
......@@ -920,7 +894,7 @@ g_buffered_input_stream_read_byte (GBufferedInputStream *stream,
if (cancellable)
g_pop_current_cancellable (cancellable);
g_input_stream_set_pending (input_stream, FALSE);
g_input_stream_clear_pending (input_stream);
if (nread <= 0)
return -1; /* error or end of stream */
......
......@@ -128,24 +128,11 @@ g_file_input_stream_query_info (GFileInputStream *stream,
input_stream = G_INPUT_STREAM (stream);
if (g_input_stream_is_closed (input_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return NULL;
}
if (g_input_stream_has_pending (input_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
return NULL;
}
if (!g_input_stream_set_pending (input_stream, error))
return NULL;
info = NULL;
g_input_stream_set_pending (input_stream, TRUE);
if (cancellable)
g_push_current_cancellable (cancellable);
......@@ -159,7 +146,7 @@ g_file_input_stream_query_info (GFileInputStream *stream,
if (cancellable)
g_pop_current_cancellable (cancellable);
g_input_stream_set_pending (input_stream, FALSE);
g_input_stream_clear_pending (input_stream);
return info;
}
......@@ -171,7 +158,7 @@ async_ready_callback_wrapper (GObject *source_object,
{
GFileInputStream *stream = G_FILE_INPUT_STREAM (source_object);
g_input_stream_set_pending (G_INPUT_STREAM (stream), FALSE);
g_input_stream_clear_pending (G_INPUT_STREAM (stream));
if (stream->priv->outstanding_callback)
(*stream->priv->outstanding_callback) (source_object, res, user_data);
g_object_unref (stream);
......@@ -205,34 +192,24 @@ g_file_input_stream_query_info_async (GFileInputStream *stream,
{
GFileInputStreamClass *klass;
GInputStream *input_stream;
GError *error = NULL;
g_return_if_fail (G_IS_FILE_INPUT_STREAM (stream));
input_stream = G_INPUT_STREAM (stream);
if (g_input_stream_is_closed (input_stream))
{
g_simple_async_report_error_in_idle (G_OBJECT (stream),
callback,
user_data,
G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return;
}
if (g_input_stream_has_pending (input_stream))
if (!g_input_stream_set_pending (input_stream, &error))
{
g_simple_async_report_error_in_idle (G_OBJECT (stream),
callback,
user_data,
G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
callback,
user_data,
error);
g_error_free (error);
return;
}
klass = G_FILE_INPUT_STREAM_GET_CLASS (stream);
g_input_stream_set_pending (input_stream, TRUE);
stream->priv->outstanding_callback = callback;
g_object_ref (stream);
klass->query_info_async (stream, attributes, io_priority, cancellable,
......@@ -372,20 +349,6 @@ g_file_input_stream_seek (GFileInputStream *stream,
input_stream = G_INPUT_STREAM (stream);
class = G_FILE_INPUT_STREAM_GET_CLASS (stream);
if (g_input_stream_is_closed (input_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return FALSE;
}
if (g_input_stream_has_pending (input_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
return FALSE;
}
if (!class->seek)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
......@@ -393,7 +356,8 @@ g_file_input_stream_seek (GFileInputStream *stream,
return FALSE;
}
g_input_stream_set_pending (input_stream, TRUE);
if (!g_input_stream_set_pending (input_stream, error))
return FALSE;
if (cancellable)
g_push_current_cancellable (cancellable);
......@@ -403,7 +367,7 @@ g_file_input_stream_seek (GFileInputStream *stream,
if (cancellable)
g_pop_current_cancellable (cancellable);
g_input_stream_set_pending (input_stream, FALSE);
g_input_stream_clear_pending (input_stream);
return res;
}
......
......@@ -138,24 +138,11 @@ g_file_output_stream_query_info (GFileOutputStream *stream,
output_stream = G_OUTPUT_STREAM (stream);
if (g_output_stream_is_closed (output_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return NULL;
}
if (g_output_stream_has_pending (output_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
return NULL;
}
if (!g_output_stream_set_pending (output_stream, error))
return NULL;
info = NULL;
g_output_stream_set_pending (output_stream, TRUE);
if (cancellable)
g_push_current_cancellable (cancellable);
......@@ -169,7 +156,7 @@ g_file_output_stream_query_info (GFileOutputStream *stream,
if (cancellable)
g_pop_current_cancellable (cancellable);
g_output_stream_set_pending (output_stream, FALSE);
g_output_stream_clear_pending (output_stream);
return info;
}
......@@ -181,7 +168,7 @@ async_ready_callback_wrapper (GObject *source_object,
{
GFileOutputStream *stream = G_FILE_OUTPUT_STREAM (source_object);
g_output_stream_set_pending (G_OUTPUT_STREAM (stream), FALSE);
g_output_stream_clear_pending (G_OUTPUT_STREAM (stream));
if (stream->priv->outstanding_callback)
(*stream->priv->outstanding_callback) (source_object, res, user_data);
g_object_unref (stream);
......@@ -215,34 +202,24 @@ g_file_output_stream_query_info_async (GFileOutputStream *stream,
{
GFileOutputStreamClass *klass;
GOutputStream *output_stream;
GError *error = NULL;
g_return_if_fail (G_IS_FILE_OUTPUT_STREAM (stream));
output_stream = G_OUTPUT_STREAM (stream);
if (g_output_stream_is_closed (output_stream))
if (!g_output_stream_set_pending (output_stream, &error))
{
g_simple_async_report_error_in_idle (G_OBJECT (stream),
callback,
user_data,
G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return;
}
if (g_output_stream_has_pending (output_stream))
{
g_simple_async_report_error_in_idle (G_OBJECT (stream),
callback,
user_data,
G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
callback,
user_data,
error);
g_error_free (error);
return;
}
klass = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
g_output_stream_set_pending (output_stream, TRUE);
stream->priv->outstanding_callback = callback;
g_object_ref (stream);
klass->query_info_async (stream, attributes, io_priority, cancellable,
......@@ -410,20 +387,6 @@ g_file_output_stream_seek (GFileOutputStream *stream,
output_stream = G_OUTPUT_STREAM (stream);
class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
if (g_output_stream_is_closed (output_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return FALSE;
}
if (g_output_stream_has_pending (output_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
return FALSE;
}
if (!class->seek)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
......@@ -431,7 +394,8 @@ g_file_output_stream_seek (GFileOutputStream *stream,
return FALSE;
}
g_output_stream_set_pending (output_stream, TRUE);
if (!g_output_stream_set_pending (output_stream, error))
return FALSE;
if (cancellable)
g_push_current_cancellable (cancellable);
......@@ -441,7 +405,7 @@ g_file_output_stream_seek (GFileOutputStream *stream,
if (cancellable)
g_pop_current_cancellable (cancellable);
g_output_stream_set_pending (output_stream, FALSE);
g_output_stream_clear_pending (output_stream);
return res;
}
......@@ -518,20 +482,6 @@ g_file_output_stream_truncate (GFileOutputStream *stream,
output_stream = G_OUTPUT_STREAM (stream);
class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
if (g_output_stream_is_closed (output_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return FALSE;
}
if (g_output_stream_has_pending (output_stream))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
return FALSE;
}
if (!class->truncate)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
......@@ -539,7 +489,8 @@ g_file_output_stream_truncate (GFileOutputStream *stream,
return FALSE;
}
g_output_stream_set_pending (output_stream, TRUE);
if (!g_output_stream_set_pending (output_stream, error))
return FALSE;
if (cancellable)
g_push_current_cancellable (cancellable);
......@@ -549,7 +500,7 @@ g_file_output_stream_truncate (GFileOutputStream *stream,
if (cancellable)
g_pop_current_cancellable (cancellable);
g_output_stream_set_pending (output_stream, FALSE);
g_output_stream_clear_pending (output_stream);
return res;
}
......
......@@ -186,20 +186,6 @@ g_input_stream_read (GInputStream *stream,
return -1;
}
if (stream->priv->closed)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return -1;
}
if (stream->priv->pending)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
return -1;
}
class = G_INPUT_STREAM_GET_CLASS (stream);
if (class->read == NULL)
......@@ -209,16 +195,19 @@ g_input_stream_read (GInputStream *stream,
return -1;
}
if (!g_input_stream_set_pending (stream, error))
return -1;
if (cancellable)
g_push_current_cancellable (cancellable);
stream->priv->pending = TRUE;
res = class->read (stream, buffer, count, cancellable, error);
stream->priv->pending = FALSE;
if (cancellable)
g_pop_current_cancellable (cancellable);
g_input_stream_clear_pending (stream);
return res;
}
......@@ -329,32 +318,21 @@ g_input_stream_skip (GInputStream *stream,
return -1;
}
if (stream->priv->closed)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return -1;
}
if (stream->priv->pending)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
return -1;
}
class = G_INPUT_STREAM_GET_CLASS (stream);
if (!g_input_stream_set_pending (stream, error))
return -1;
if (cancellable)
g_push_current_cancellable (cancellable);
stream->priv->pending = TRUE;
res = class->skip (stream, count, cancellable, error);
stream->priv->pending = FALSE;
if (cancellable)
g_pop_current_cancellable (cancellable);
g_input_stream_clear_pending (stream);
return res;
}
......@@ -461,16 +439,10 @@ g_input_stream_close (GInputStream *stream,
if (stream->priv->closed)
return TRUE;
if (stream->priv->pending)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
return FALSE;
}
res = TRUE;
stream->priv->pending = TRUE;
if (!g_input_stream_set_pending (stream, error))
return FALSE;
if (cancellable)
g_push_current_cancellable (cancellable);
......@@ -480,11 +452,11 @@ g_input_stream_close (GInputStream *stream,
if (cancellable)
g_pop_current_cancellable (cancellable);
g_input_stream_clear_pending (stream);
stream->priv->closed = TRUE;
stream->priv->pending = FALSE;
return res;
}
......@@ -495,7 +467,7 @@ async_ready_callback_wrapper (GObject *source_object,
{
GInputStream *stream = G_INPUT_STREAM (source_object);
stream->priv->pending = FALSE;
g_input_stream_clear_pending (stream);
if (stream->priv->outstanding_callback)
(*stream->priv->outstanding_callback) (source_object, res, user_data);
g_object_unref (stream);
......@@ -508,7 +480,7 @@ async_ready_close_callback_wrapper (GObject *source_object,
{
GInputStream *stream = G_INPUT_STREAM (source_object);
stream->priv->pending = FALSE;
g_input_stream_clear_pending (stream);
stream->priv->closed = TRUE;
if (stream->priv->outstanding_callback)
(*stream->priv->outstanding_callback) (source_object, res, user_data);
......@@ -560,6 +532,7 @@ g_input_stream_read_async (GInputStream *stream,
{
GInputStreamClass *class;
GSimpleAsyncResult *simple;
GError *error = NULL;
g_return_if_fail (G_IS_INPUT_STREAM (stream));
g_return_if_fail (buffer != NULL);
......@@ -585,29 +558,17 @@ g_input_stream_read_async (GInputStream *stream,
return;
}
if (stream->priv->closed)
{
g_simple_async_report_error_in_idle (G_OBJECT (stream),
callback,
user_data,
G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return;
}
if (stream->priv->pending)
if (!g_input_stream_set_pending (stream, &error))
{
g_simple_async_report_error_in_idle (G_OBJECT (stream),
callback,
user_data,
G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
callback,
user_data,
error);
g_error_free (error);
return;
}
class = G_INPUT_STREAM_GET_CLASS (stream);
stream->priv->pending = TRUE;
stream->priv->outstanding_callback = callback;
g_object_ref (stream);
class->read_async (stream, buffer, count, io_priority, cancellable,
......@@ -694,6 +655,7 @@ g_input_stream_skip_async (GInputStream *stream,
{
GInputStreamClass *class;
GSimpleAsyncResult *simple;
GError *error = NULL;
g_return_if_fail (G_IS_INPUT_STREAM (stream));
......@@ -719,28 +681,17 @@ g_input_stream_skip_async (GInputStream *stream,
return;
}
if (stream->priv->closed)
if (!g_input_stream_set_pending (stream, &error))
{
g_simple_async_report_error_in_idle (G_OBJECT (stream),
callback,
user_data,
G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return;
}
if (stream->priv->pending)
{
g_simple_async_report_error_in_idle (G_OBJECT (stream),
callback,
user_data,
G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
callback,
user_data,
error);
g_error_free (error);
return;
}
class = G_INPUT_STREAM_GET_CLASS (stream);
stream->priv->pending = TRUE;
stream->priv->outstanding_callback = callback;
g_object_ref (stream);
class->skip_async (stream, count, io_priority, cancellable,
......@@ -811,6 +762,7 @@ g_input_stream_close_async (GInputStream *stream,
{
GInputStreamClass *class;
GSimpleAsyncResult *simple;
GError *error = NULL;
g_return_if_fail (G_IS_INPUT_STREAM (stream));
......@@ -826,18 +778,17 @@ g_input_stream_close_async (GInputStream *stream,
return;
}
if (stream->priv->pending)
if (!g_input_stream_set_pending (stream, &error))
{
g_simple_async_report_error_in_idle (G_OBJECT (stream),
callback,
user_data,
G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
callback,
user_data,
error);
g_error_free (error);
return;
}
class = G_INPUT_STREAM_GET_CLASS (stream);
stream->priv->pending = TRUE;
stream->priv->outstanding_callback = callback;
g_object_ref (stream);
class->close_async (stream, io_priority, cancellable,
......@@ -916,17 +867,50 @@ g_input_stream_has_pending (GInputStream *stream)
/**
* g_input_stream_set_pending:
* @stream: input stream
* @pending: boolean.
* @error: a #GError location to store the error occuring, or %NULL to
* ignore.
*
* Sets @stream to have actions pending. If the pending flag is
* already set or @stream is closed, it will return %FALSE and set
* @error.
*
* Return value: %TRUE if pending was previously unset and is now set.
**/
gboolean
g_input_stream_set_pending (GInputStream *stream, GError **error)
{
g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
if (stream->priv->closed)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Stream is already closed"));
return FALSE;
}
if (stream->priv->pending)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
_("Stream has outstanding operation"));
return FALSE;
}
stream->priv->pending = TRUE;
return TRUE;
}
/**
* g_input_stream_clear_pending:
* @stream: input stream
*
* Sets @stream has actions pending.
* Clears the pending flag on @stream.
**/
void
g_input_stream_set_pending (GInputStream *stream,
gboolean pending)
g_input_stream_clear_pending (GInputStream *stream)
{
g_return_if_fail (G_IS_INPUT_STREAM (stream));
stream->priv->pending = pending;
stream->priv->pending = FALSE;
}
/********************************************
......
......@@ -113,58 +113,59 @@ struct _GInputStreamClass
GType g_input_stream_get_type (void) G_GNUC_CONST;
gssize g_input_stream_read (GInputStream *stream,
void *buffer,
gsize count,
GCancellable *cancellable,
GError **error);
gboolean g_input_stream_read_all (GInputStream *stream,
void *buffer,
gsize count,
gsize *bytes_read,
GCancellable *cancellable,
GError **error);
gssize g_input_stream_skip (GInputStream *stream,
gsize count,
GCancellable *cancellable,
GError **error);