From 117de38f04de4f546215957b95d3c5b3f104fa42 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Tue, 4 Dec 2007 08:57:04 +0000 Subject: [PATCH] Make this take a GError and return a gboolean, and do the "outstanding 2007-11-30 Dan Winship * 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 --- gio/ChangeLog | 18 ++++ gio/gbufferedinputstream.c | 62 ++++--------- gio/gfileinputstream.c | 64 +++---------- gio/gfileoutputstream.c | 83 ++++------------- gio/ginputstream.c | 166 ++++++++++++++++------------------ gio/ginputstream.h | 99 ++++++++++---------- gio/goutputstream.c | 218 +++++++++++++++++++-------------------------- gio/goutputstream.h | 5 +- gio/gsimpleasyncresult.c | 28 ++++++ gio/gsimpleasyncresult.h | 18 ++-- 10 files changed, 325 insertions(+), 436 deletions(-) diff --git a/gio/ChangeLog b/gio/ChangeLog index 54d6a14..62e85b7 100644 --- a/gio/ChangeLog +++ b/gio/ChangeLog @@ -1,5 +1,23 @@ 2007-11-30 Dan Winship + * 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 + * goutputstream.c: Don't cheat and unset the "pending" flag around inner calls. Instead, call the class method directly rather than the wrapper function that checks "pending" diff --git a/gio/gbufferedinputstream.c b/gio/gbufferedinputstream.c index 8c0137c..66d522a 100644 --- a/gio/gbufferedinputstream.c +++ b/gio/gbufferedinputstream.c @@ -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 */ diff --git a/gio/gfileinputstream.c b/gio/gfileinputstream.c index f26a34d..adaac3d 100644 --- a/gio/gfileinputstream.c +++ b/gio/gfileinputstream.c @@ -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; } diff --git a/gio/gfileoutputstream.c b/gio/gfileoutputstream.c index cdaeb4e..e23a34f 100644 --- a/gio/gfileoutputstream.c +++ b/gio/gfileoutputstream.c @@ -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; } diff --git a/gio/ginputstream.c b/gio/ginputstream.c index bb49ff9..f73602c 100644 --- a/gio/ginputstream.c +++ b/gio/ginputstream.c @@ -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; } /******************************************** diff --git a/gio/ginputstream.h b/gio/ginputstream.h index c6ec443..279cd65 100644 --- a/gio/ginputstream.h +++ b/gio/ginputstream.h @@ -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); -gboolean g_input_stream_close (GInputStream *stream, - GCancellable *cancellable, - GError **error); -void g_input_stream_read_async (GInputStream *stream, - void *buffer, - gsize count, - int io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gssize g_input_stream_read_finish (GInputStream *stream, - GAsyncResult *result, - GError **error); -void g_input_stream_skip_async (GInputStream *stream, - gsize count, - int io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gssize g_input_stream_skip_finish (GInputStream *stream, - GAsyncResult *result, - GError **error); -void g_input_stream_close_async (GInputStream *stream, - int io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean g_input_stream_close_finish (GInputStream *stream, - GAsyncResult *result, - GError **error); +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); +gboolean g_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error); +void g_input_stream_read_async (GInputStream *stream, + void *buffer, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gssize g_input_stream_read_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); +void g_input_stream_skip_async (GInputStream *stream, + gsize count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gssize g_input_stream_skip_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); +void g_input_stream_close_async (GInputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean g_input_stream_close_finish (GInputStream *stream, + GAsyncResult *result, + GError **error); /* For implementations: */ -gboolean g_input_stream_is_closed (GInputStream *stream); -gboolean g_input_stream_has_pending (GInputStream *stream); -void g_input_stream_set_pending (GInputStream *stream, - gboolean pending); +gboolean g_input_stream_is_closed (GInputStream *stream); +gboolean g_input_stream_has_pending (GInputStream *stream); +gboolean g_input_stream_set_pending (GInputStream *stream, + GError **error); +void g_input_stream_clear_pending (GInputStream *stream); G_END_DECLS diff --git a/gio/goutputstream.c b/gio/goutputstream.c index 1b75e8c..458c33e 100644 --- a/gio/goutputstream.c +++ b/gio/goutputstream.c @@ -194,20 +194,6 @@ g_output_stream_write (GOutputStream *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_OUTPUT_STREAM_GET_CLASS (stream); if (class->write == NULL) @@ -217,16 +203,19 @@ g_output_stream_write (GOutputStream *stream, return -1; } + if (!g_output_stream_set_pending (stream, error)) + return -1; + if (cancellable) g_push_current_cancellable (cancellable); - stream->priv->pending = TRUE; res = class->write (stream, buffer, count, cancellable, error); - stream->priv->pending = FALSE; if (cancellable) g_pop_current_cancellable (cancellable); + g_output_stream_clear_pending (stream); + return res; } @@ -320,19 +309,8 @@ g_output_stream_flush (GOutputStream *stream, g_return_val_if_fail (G_IS_OUTPUT_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; - } + if (!g_output_stream_set_pending (stream, error)) + return FALSE; class = G_OUTPUT_STREAM_GET_CLASS (stream); @@ -342,14 +320,14 @@ g_output_stream_flush (GOutputStream *stream, if (cancellable) g_push_current_cancellable (cancellable); - stream->priv->pending = TRUE; res = class->flush (stream, cancellable, error); - stream->priv->pending = FALSE; if (cancellable) g_pop_current_cancellable (cancellable); } + g_output_stream_clear_pending (stream); + return res; } @@ -379,13 +357,6 @@ g_output_stream_splice (GOutputStream *stream, g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1); g_return_val_if_fail (G_IS_INPUT_STREAM (source), -1); - if (stream->priv->closed) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED, - _("Target stream is already closed")); - return -1; - } - if (g_input_stream_is_closed (source)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED, @@ -393,12 +364,8 @@ g_output_stream_splice (GOutputStream *stream, return -1; } - if (stream->priv->pending) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING, - _("Stream has outstanding operation")); - return -1; - } + if (!g_output_stream_set_pending (stream, error)) + return -1; class = G_OUTPUT_STREAM_GET_CLASS (stream); @@ -406,13 +373,13 @@ g_output_stream_splice (GOutputStream *stream, if (cancellable) g_push_current_cancellable (cancellable); - stream->priv->pending = TRUE; res = class->splice (stream, source, flags, cancellable, error); - stream->priv->pending = FALSE; if (cancellable) g_pop_current_cancellable (cancellable); + g_output_stream_clear_pending (stream); + return res; } @@ -545,20 +512,14 @@ g_output_stream_close (GOutputStream *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; - } + if (!g_output_stream_set_pending (stream, error)) + return FALSE; - stream->priv->pending = TRUE; - if (cancellable) g_push_current_cancellable (cancellable); res = class->flush (stream, cancellable, error); - + if (!res) { /* flushing caused the error that we want to return, @@ -578,7 +539,7 @@ g_output_stream_close (GOutputStream *stream, g_pop_current_cancellable (cancellable); stream->priv->closed = TRUE; - stream->priv->pending = FALSE; + g_output_stream_clear_pending (stream); return res; } @@ -590,7 +551,7 @@ async_ready_callback_wrapper (GObject *source_object, { GOutputStream *stream = G_OUTPUT_STREAM (source_object); - stream->priv->pending = FALSE; + g_output_stream_clear_pending (stream); if (stream->priv->outstanding_callback) (*stream->priv->outstanding_callback) (source_object, res, user_data); g_object_unref (stream); @@ -603,8 +564,8 @@ async_ready_close_callback_wrapper (GObject *source_object, { GOutputStream *stream = G_OUTPUT_STREAM (source_object); - stream->priv->pending = FALSE; stream->priv->closed = TRUE; + g_output_stream_clear_pending (stream); if (stream->priv->outstanding_callback) (*stream->priv->outstanding_callback) (source_object, res, user_data); g_object_unref (stream); @@ -657,6 +618,7 @@ g_output_stream_write_async (GOutputStream *stream, { GOutputStreamClass *class; GSimpleAsyncResult *simple; + GError *error = NULL; g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); g_return_if_fail (buffer != NULL); @@ -682,29 +644,18 @@ g_output_stream_write_async (GOutputStream *stream, return; } - if (stream->priv->closed) + if (!g_output_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")); + g_simple_async_report_gerror_in_idle (G_OBJECT (stream), + callback, + user_data, + error); + g_error_free (error); 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")); - return; - } - class = G_OUTPUT_STREAM_GET_CLASS (stream); - stream->priv->pending = TRUE; stream->priv->outstanding_callback = callback; g_object_ref (stream); class->write_async (stream, buffer, count, io_priority, cancellable, @@ -762,7 +713,7 @@ async_ready_splice_callback_wrapper (GObject *source_object, GOutputStream *stream = G_OUTPUT_STREAM (source_object); SpliceUserData *data = _data; - stream->priv->pending = FALSE; + g_output_stream_clear_pending (stream); if (data->callback) (*data->callback) (source_object, res, data->user_data); @@ -796,20 +747,11 @@ g_output_stream_splice_async (GOutputStream *stream, { GOutputStreamClass *class; SpliceUserData *data; + GError *error = NULL; g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); g_return_if_fail (G_IS_INPUT_STREAM (source)); - if (stream->priv->closed) - { - g_simple_async_report_error_in_idle (G_OBJECT (stream), - callback, - user_data, - G_IO_ERROR, G_IO_ERROR_CLOSED, - _("Target stream is already closed")); - return; - } - if (g_input_stream_is_closed (source)) { g_simple_async_report_error_in_idle (G_OBJECT (stream), @@ -820,20 +762,18 @@ g_output_stream_splice_async (GOutputStream *stream, return; } - if (stream->priv->pending) + if (!g_output_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_OUTPUT_STREAM_GET_CLASS (stream); - stream->priv->pending = TRUE; - data = g_new0 (SpliceUserData, 1); data->callback = callback; data->user_data = user_data; @@ -897,35 +837,29 @@ g_output_stream_flush_async (GOutputStream *stream, { GOutputStreamClass *class; GSimpleAsyncResult *simple; + GError *error = NULL; g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); - if (stream->priv->closed) + if (!g_output_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; } + stream->priv->outstanding_callback = callback; + g_object_ref (stream); + class = G_OUTPUT_STREAM_GET_CLASS (stream); if (class->flush_async == NULL) { simple = g_simple_async_result_new (G_OBJECT (stream), - callback, + async_ready_callback_wrapper, user_data, g_output_stream_flush_async); g_simple_async_result_complete_in_idle (simple); @@ -933,9 +867,6 @@ g_output_stream_flush_async (GOutputStream *stream, return; } - stream->priv->pending = TRUE; - stream->priv->outstanding_callback = callback; - g_object_ref (stream); class->flush_async (stream, io_priority, cancellable, async_ready_callback_wrapper, user_data); } @@ -1005,6 +936,7 @@ g_output_stream_close_async (GOutputStream *stream, { GOutputStreamClass *class; GSimpleAsyncResult *simple; + GError *error = NULL; g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); @@ -1019,18 +951,17 @@ g_output_stream_close_async (GOutputStream *stream, return; } - if (stream->priv->pending) + if (!g_output_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_OUTPUT_STREAM_GET_CLASS (stream); - stream->priv->pending = TRUE; stream->priv->outstanding_callback = callback; g_object_ref (stream); class->close_async (stream, io_priority, cancellable, @@ -1109,17 +1040,51 @@ g_output_stream_has_pending (GOutputStream *stream) /** * g_output_stream_set_pending: * @stream: a #GOutputStream. - * @pending: a #gboolean. + * @error: a #GError location to store the error occuring, or %NULL to + * ignore. * - * Sets the @stream as having pending actions if @pending is %TRUE. + * 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. **/ -void +gboolean g_output_stream_set_pending (GOutputStream *stream, - gboolean pending) + GError **error) +{ + g_return_val_if_fail (G_IS_OUTPUT_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_output_stream_clear_pending: + * @stream: output stream + * + * Clears the pending flag on @stream. + **/ +void +g_output_stream_clear_pending (GOutputStream *stream) { g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); - stream->priv->pending = pending; + stream->priv->pending = FALSE; } @@ -1213,7 +1178,6 @@ splice_async_thread (GSimpleAsyncResult *result, op->flags, cancellable, &error); - if (op->bytes_copied == -1) { g_simple_async_result_set_from_error (result, error); diff --git a/gio/goutputstream.h b/gio/goutputstream.h index d62afc2..a526125 100644 --- a/gio/goutputstream.h +++ b/gio/goutputstream.h @@ -211,8 +211,9 @@ gboolean g_output_stream_close_finish (GOutputStream *stream, gboolean g_output_stream_is_closed (GOutputStream *stream); gboolean g_output_stream_has_pending (GOutputStream *stream); -void g_output_stream_set_pending (GOutputStream *stream, - gboolean pending); +gboolean g_output_stream_set_pending (GOutputStream *stream, + GError **error); +void g_output_stream_clear_pending (GOutputStream *stream); G_END_DECLS diff --git a/gio/gsimpleasyncresult.c b/gio/gsimpleasyncresult.c index 81d1005..b3f62eb 100644 --- a/gio/gsimpleasyncresult.c +++ b/gio/gsimpleasyncresult.c @@ -682,5 +682,33 @@ g_simple_async_report_error_in_idle (GObject *object, g_object_unref (simple); } +/** + * g_simple_async_report_error_in_idle: + * @object: a #GObject. + * @callback: a #GAsyncReadyCallback. + * @user_data: user data passed to @callback. + * @error: the #GError to report + * + * Reports an error in an idle function. + **/ +void +g_simple_async_report_gerror_in_idle (GObject *object, + GAsyncReadyCallback callback, + gpointer user_data, + GError *error) +{ + GSimpleAsyncResult *simple; + + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (error != NULL); + + simple = g_simple_async_result_new_from_error (object, + callback, + user_data, + error); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); +} + #define __G_SIMPLE_ASYNC_RESULT_C__ #include "gioaliasdef.c" diff --git a/gio/gsimpleasyncresult.h b/gio/gsimpleasyncresult.h index 0607f88..f1ab938 100644 --- a/gio/gsimpleasyncresult.h +++ b/gio/gsimpleasyncresult.h @@ -114,13 +114,17 @@ void g_simple_async_result_set_error_va (GSimpleAsyncResult const char *format, va_list args); -void g_simple_async_report_error_in_idle (GObject *object, - GAsyncReadyCallback callback, - gpointer user_data, - GQuark domain, - gint code, - const char *format, - ...); +void g_simple_async_report_error_in_idle (GObject *object, + GAsyncReadyCallback callback, + gpointer user_data, + GQuark domain, + gint code, + const char *format, + ...); +void g_simple_async_report_gerror_in_idle (GObject *object, + GAsyncReadyCallback callback, + gpointer user_data, + GError *error); G_END_DECLS -- 2.7.4