[glib/wip/task: 5/11] gio: port basic I/O classes from GSimpleAsyncResult to GTask
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/task: 5/11] gio: port basic I/O classes from GSimpleAsyncResult to GTask
- Date: Thu, 2 Aug 2012 20:34:08 +0000 (UTC)
commit 6db435bdde9b655228223510310757624fd54a37
Author: Dan Winship <danw gnome org>
Date: Thu Aug 2 15:49:59 2012 -0400
gio: port basic I/O classes from GSimpleAsyncResult to GTask
NOTE: Needs maintainer sanity-checking before being merged to master.
https://bugzilla.gnome.org/show_bug.cgi?id=661767
gio/gbufferedinputstream.c | 164 +++++------
gio/gbufferedoutputstream.c | 73 ++---
gio/gdatainputstream.c | 139 ++++------
gio/ginputstream.c | 408 ++++++++++---------------
gio/giostream.c | 177 +++++------
gio/gmemoryinputstream.c | 36 +--
gio/gmemoryoutputstream.c | 23 +-
gio/goutputstream.c | 686 ++++++++++++++++++++-----------------------
gio/gunixinputstream.c | 110 +++-----
gio/gunixoutputstream.c | 106 +++-----
10 files changed, 803 insertions(+), 1119 deletions(-)
---
diff --git a/gio/gbufferedinputstream.c b/gio/gbufferedinputstream.c
index dd98d98..d03eea5 100644
--- a/gio/gbufferedinputstream.c
+++ b/gio/gbufferedinputstream.c
@@ -26,7 +26,7 @@
#include "ginputstream.h"
#include "gcancellable.h"
#include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
#include "gseekable.h"
#include "gioerror.h"
#include <string.h>
@@ -483,39 +483,37 @@ g_buffered_input_stream_fill_async (GBufferedInputStream *stream,
gpointer user_data)
{
GBufferedInputStreamClass *class;
- GSimpleAsyncResult *simple;
+ GTask *task;
GError *error = NULL;
g_return_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream));
if (count == 0)
{
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- user_data,
- g_buffered_input_stream_fill_async);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_buffered_input_stream_fill_async);
+ g_task_return_int (task, 0);
+ g_object_unref (task);
return;
}
if (count < -1)
{
- g_simple_async_report_error_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- _("Too large count value passed to %s"),
- G_STRFUNC);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_buffered_input_stream_fill_async);
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ _("Too large count value passed to %s"),
+ G_STRFUNC);
+ g_object_unref (task);
return;
}
if (!g_input_stream_set_pending (G_INPUT_STREAM (stream), &error))
{
- g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- error);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_buffered_input_stream_fill_async);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
@@ -1041,38 +1039,28 @@ fill_async_callback (GObject *source_object,
{
GError *error;
gssize res;
- GSimpleAsyncResult *simple;
-
- simple = user_data;
+ GTask *task = user_data;
error = NULL;
res = g_input_stream_read_finish (G_INPUT_STREAM (source_object),
result, &error);
-
- g_simple_async_result_set_op_res_gssize (simple, res);
if (res == -1)
- {
- g_simple_async_result_take_error (simple, error);
- }
+ g_task_return_error (task, error);
else
{
+ GBufferedInputStream *stream;
GBufferedInputStreamPrivate *priv;
- GObject *object;
- object = g_async_result_get_source_object (G_ASYNC_RESULT (simple));
- priv = G_BUFFERED_INPUT_STREAM (object)->priv;
+ stream = g_task_get_source_object (task);
+ priv = G_BUFFERED_INPUT_STREAM (stream)->priv;
g_assert_cmpint (priv->end + res, <=, priv->len);
priv->end += res;
- g_object_unref (object);
+ g_task_return_int (task, res);
}
- /* Complete immediately, not in idle, since we're already
- * in a mainloop callout
- */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_object_unref (task);
}
static void
@@ -1085,7 +1073,7 @@ g_buffered_input_stream_real_fill_async (GBufferedInputStream *stream,
{
GBufferedInputStreamPrivate *priv;
GInputStream *base_stream;
- GSimpleAsyncResult *simple;
+ GTask *task;
gsize in_buffer;
priv = stream->priv;
@@ -1102,9 +1090,7 @@ g_buffered_input_stream_real_fill_async (GBufferedInputStream *stream,
if (priv->len - priv->end < count)
compact_buffer (stream);
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback, user_data,
- g_buffered_input_stream_real_fill_async);
+ task = g_task_new (stream, cancellable, callback, user_data);
base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
g_input_stream_read_async (base_stream,
@@ -1113,7 +1099,7 @@ g_buffered_input_stream_real_fill_async (GBufferedInputStream *stream,
io_priority,
cancellable,
fill_async_callback,
- simple);
+ task);
}
static gssize
@@ -1121,17 +1107,9 @@ g_buffered_input_stream_real_fill_finish (GBufferedInputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
- gssize nread;
+ g_return_val_if_fail (g_task_is_valid (result, stream), -1);
- simple = G_SIMPLE_ASYNC_RESULT (result);
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_real_fill_async);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return -1;
-
- nread = g_simple_async_result_get_op_res_gssize (simple);
- return nread;
+ return g_task_propagate_int (G_TASK (result), error);
}
typedef struct
@@ -1152,12 +1130,12 @@ large_skip_callback (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+ GTask *task = G_TASK (user_data);
SkipAsyncData *data;
GError *error;
gssize nread;
- data = g_simple_async_result_get_op_res_gpointer (simple);
+ data = g_task_get_task_data (task);
error = NULL;
nread = g_input_stream_skip_finish (G_INPUT_STREAM (source_object),
@@ -1165,18 +1143,19 @@ large_skip_callback (GObject *source_object,
/* Only report the error if we've not already read some data */
if (nread < 0 && data->bytes_skipped == 0)
- g_simple_async_result_take_error (simple, error);
- else if (error)
- g_error_free (error);
+ g_task_return_error (task, error);
+ else
+ {
+ if (error)
+ g_error_free (error);
- if (nread > 0)
- data->bytes_skipped += nread;
+ if (nread > 0)
+ data->bytes_skipped += nread;
- /* Complete immediately, not in idle, since we're already
- * in a mainloop callout
- */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_int (task, data->bytes_skipped);
+ }
+
+ g_object_unref (task);
}
static void
@@ -1184,7 +1163,7 @@ skip_fill_buffer_callback (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+ GTask *task = G_TASK (user_data);
GBufferedInputStream *bstream;
GBufferedInputStreamPrivate *priv;
SkipAsyncData *data;
@@ -1195,31 +1174,32 @@ skip_fill_buffer_callback (GObject *source_object,
bstream = G_BUFFERED_INPUT_STREAM (source_object);
priv = bstream->priv;
- data = g_simple_async_result_get_op_res_gpointer (simple);
+ data = g_task_get_task_data (task);
error = NULL;
nread = g_buffered_input_stream_fill_finish (bstream,
result, &error);
if (nread < 0 && data->bytes_skipped == 0)
- g_simple_async_result_take_error (simple, error);
- else if (error)
- g_error_free (error);
-
- if (nread > 0)
+ g_task_return_error (task, error);
+ else
{
- available = priv->end - priv->pos;
- data->count = MIN (data->count, available);
+ if (error)
+ g_error_free (error);
+
+ if (nread > 0)
+ {
+ available = priv->end - priv->pos;
+ data->count = MIN (data->count, available);
- data->bytes_skipped += data->count;
- priv->pos += data->count;
+ data->bytes_skipped += data->count;
+ priv->pos += data->count;
+ }
+
+ g_task_return_int (task, data->bytes_skipped);
}
- /* Complete immediately, not in idle, since we're already
- * in a mainloop callout
- */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_object_unref (task);
}
static void
@@ -1235,7 +1215,7 @@ g_buffered_input_stream_skip_async (GInputStream *stream,
GBufferedInputStreamClass *class;
GInputStream *base_stream;
gsize available;
- GSimpleAsyncResult *simple;
+ GTask *task;
SkipAsyncData *data;
bstream = G_BUFFERED_INPUT_STREAM (stream);
@@ -1243,20 +1223,17 @@ g_buffered_input_stream_skip_async (GInputStream *stream,
data = g_slice_new (SkipAsyncData);
data->bytes_skipped = 0;
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback, user_data,
- g_buffered_input_stream_skip_async);
- g_simple_async_result_set_op_res_gpointer (simple, data, free_skip_async_data);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_task_data (task, data, free_skip_async_data);
available = priv->end - priv->pos;
if (count <= available)
{
priv->pos += count;
- data->bytes_skipped = count;
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ g_task_return_int (task, count);
+ g_object_unref (task);
return;
}
@@ -1282,13 +1259,13 @@ g_buffered_input_stream_skip_async (GInputStream *stream,
count,
io_priority, cancellable,
large_skip_callback,
- simple);
+ task);
}
else
{
class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
class->fill_async (bstream, priv->len, io_priority, cancellable,
- skip_fill_buffer_callback, simple);
+ skip_fill_buffer_callback, task);
}
}
@@ -1297,14 +1274,7 @@ g_buffered_input_stream_skip_finish (GInputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
- SkipAsyncData *data;
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
-
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_skip_async);
-
- data = g_simple_async_result_get_op_res_gpointer (simple);
+ g_return_val_if_fail (g_task_is_valid (result, stream), -1);
- return data->bytes_skipped;
+ return g_task_propagate_int (G_TASK (result), error);
}
diff --git a/gio/gbufferedoutputstream.c b/gio/gbufferedoutputstream.c
index f52ad2f..b62d04d 100644
--- a/gio/gbufferedoutputstream.c
+++ b/gio/gbufferedoutputstream.c
@@ -24,7 +24,7 @@
#include "gbufferedoutputstream.h"
#include "goutputstream.h"
#include "gseekable.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
#include "string.h"
#include "gioerror.h"
#include "glibintl.h"
@@ -652,9 +652,10 @@ free_flush_data (gpointer data)
* and so closing and writing is just a special
* case of flushing + some addition stuff */
static void
-flush_buffer_thread (GSimpleAsyncResult *result,
- GObject *object,
- GCancellable *cancellable)
+flush_buffer_thread (GTask *task,
+ gpointer object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
GBufferedOutputStream *stream;
GOutputStream *base_stream;
@@ -663,7 +664,7 @@ flush_buffer_thread (GSimpleAsyncResult *result,
GError *error = NULL;
stream = G_BUFFERED_OUTPUT_STREAM (object);
- fdata = g_simple_async_result_get_op_res_gpointer (result);
+ fdata = task_data;
base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream;
res = flush_buffer (stream, cancellable, &error);
@@ -689,7 +690,9 @@ flush_buffer_thread (GSimpleAsyncResult *result,
}
if (res == FALSE)
- g_simple_async_result_take_error (result, error);
+ g_task_return_error (task, error);
+ else
+ g_task_return_boolean (task, TRUE);
}
static void
@@ -699,25 +702,19 @@ g_buffered_output_stream_flush_async (GOutputStream *stream,
GAsyncReadyCallback callback,
gpointer data)
{
- GSimpleAsyncResult *res;
- FlushData *fdata;
+ GTask *task;
+ FlushData *fdata;
fdata = g_slice_new (FlushData);
fdata->flush_stream = TRUE;
fdata->close_stream = FALSE;
- res = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- data,
- g_buffered_output_stream_flush_async);
-
- g_simple_async_result_set_op_res_gpointer (res, fdata, free_flush_data);
+ task = g_task_new (stream, cancellable, callback, data);
+ g_task_set_task_data (task, fdata, free_flush_data);
+ g_task_set_priority (task, io_priority);
- g_simple_async_result_run_in_thread (res,
- flush_buffer_thread,
- io_priority,
- cancellable);
- g_object_unref (res);
+ g_task_run_in_thread (task, flush_buffer_thread);
+ g_object_unref (task);
}
static gboolean
@@ -725,14 +722,9 @@ g_buffered_output_stream_flush_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
-
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) ==
- g_buffered_output_stream_flush_async);
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
- return TRUE;
+ return g_task_propagate_boolean (G_TASK (result), error);
}
static void
@@ -742,24 +734,18 @@ g_buffered_output_stream_close_async (GOutputStream *stream,
GAsyncReadyCallback callback,
gpointer data)
{
- GSimpleAsyncResult *res;
- FlushData *fdata;
+ GTask *task;
+ FlushData *fdata;
fdata = g_slice_new (FlushData);
fdata->close_stream = TRUE;
- res = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- data,
- g_buffered_output_stream_close_async);
+ task = g_task_new (stream, cancellable, callback, data);
+ g_task_set_task_data (task, fdata, free_flush_data);
+ g_task_set_priority (task, io_priority);
- g_simple_async_result_set_op_res_gpointer (res, fdata, free_flush_data);
-
- g_simple_async_result_run_in_thread (res,
- flush_buffer_thread,
- io_priority,
- cancellable);
- g_object_unref (res);
+ g_task_run_in_thread (task, flush_buffer_thread);
+ g_object_unref (task);
}
static gboolean
@@ -767,12 +753,7 @@ g_buffered_output_stream_close_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
-
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) ==
- g_buffered_output_stream_close_async);
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
- return TRUE;
+ return g_task_propagate_boolean (G_TASK (result), error);
}
diff --git a/gio/gdatainputstream.c b/gio/gdatainputstream.c
index ea26aeb..75a8cb5 100644
--- a/gio/gdatainputstream.c
+++ b/gio/gdatainputstream.c
@@ -24,7 +24,7 @@
#include "config.h"
#include "gdatainputstream.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
#include "gcancellable.h"
#include "gioenumtypes.h"
#include "gioerror.h"
@@ -952,49 +952,41 @@ g_data_input_stream_read_until (GDataInputStream *stream,
typedef struct
{
- GDataInputStream *stream;
- GSimpleAsyncResult *simple;
gboolean last_saw_cr;
gsize checked;
- gint io_priority;
- GCancellable *cancellable;
gchar *stop_chars;
gssize stop_chars_len;
- gchar *line;
gsize length;
} GDataInputStreamReadData;
static void
-g_data_input_stream_read_complete (GDataInputStreamReadData *data,
- gsize read_length,
- gsize skip_length,
- gboolean need_idle_dispatch)
+g_data_input_stream_read_complete (GTask *task,
+ gsize read_length,
+ gsize skip_length)
{
+ GDataInputStreamReadData *data = g_task_get_task_data (task);
+ GInputStream *stream = g_task_get_source_object (task);
+ char *line = NULL;
+
if (read_length || skip_length)
{
gssize bytes;
data->length = read_length;
- data->line = g_malloc (read_length + 1);
- data->line[read_length] = '\0';
+ line = g_malloc (read_length + 1);
+ line[read_length] = '\0';
/* we already checked the buffer. this shouldn't fail. */
- bytes = g_input_stream_read (G_INPUT_STREAM (data->stream),
- data->line, read_length, NULL, NULL);
+ bytes = g_input_stream_read (stream, line, read_length, NULL, NULL);
g_assert_cmpint (bytes, ==, read_length);
- bytes = g_input_stream_skip (G_INPUT_STREAM (data->stream),
- skip_length, NULL, NULL);
+ bytes = g_input_stream_skip (stream, skip_length, NULL, NULL);
g_assert_cmpint (bytes, ==, skip_length);
}
- if (need_idle_dispatch)
- g_simple_async_result_complete_in_idle (data->simple);
- else
- g_simple_async_result_complete (data->simple);
-
- g_object_unref (data->simple);
+ g_task_return_pointer (task, line, g_free);
+ g_object_unref (task);
}
static void
@@ -1002,14 +994,15 @@ g_data_input_stream_read_line_ready (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
- GDataInputStreamReadData *data = user_data;
+ GTask *task = user_data;
+ GDataInputStreamReadData *data = g_task_get_task_data (task);
+ GBufferedInputStream *buffer = g_task_get_source_object (task);
gssize found_pos;
gint newline_len;
if (result)
/* this is a callback. finish the async call. */
{
- GBufferedInputStream *buffer = G_BUFFERED_INPUT_STREAM (data->stream);
GError *error = NULL;
gssize bytes;
@@ -1018,13 +1011,14 @@ g_data_input_stream_read_line_ready (GObject *object,
if (bytes <= 0)
{
if (bytes < 0)
- /* stream error. */
- {
- g_simple_async_result_take_error (data->simple, error);
- data->checked = 0;
- }
+ /* stream error. */
+ {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
- g_data_input_stream_read_complete (data, data->checked, 0, FALSE);
+ g_data_input_stream_read_complete (task, data->checked, 0);
return;
}
@@ -1033,20 +1027,19 @@ g_data_input_stream_read_line_ready (GObject *object,
if (data->stop_chars)
{
- found_pos = scan_for_chars (data->stream,
+ found_pos = scan_for_chars (G_DATA_INPUT_STREAM (buffer),
&data->checked,
data->stop_chars,
data->stop_chars_len);
newline_len = 0;
}
else
- found_pos = scan_for_newline (data->stream, &data->checked,
+ found_pos = scan_for_newline (G_DATA_INPUT_STREAM (buffer), &data->checked,
&data->last_saw_cr, &newline_len);
if (found_pos == -1)
/* didn't find a full line; need to buffer some more bytes */
{
- GBufferedInputStream *buffer = G_BUFFERED_INPUT_STREAM (data->stream);
gsize size;
size = g_buffered_input_stream_get_buffer_size (buffer);
@@ -1056,16 +1049,16 @@ g_data_input_stream_read_line_ready (GObject *object,
g_buffered_input_stream_set_buffer_size (buffer, size * 2);
/* try again */
- g_buffered_input_stream_fill_async (buffer, -1, data->io_priority,
- data->cancellable,
+ g_buffered_input_stream_fill_async (buffer, -1,
+ g_task_get_priority (task),
+ g_task_get_cancellable (task),
g_data_input_stream_read_line_ready,
user_data);
}
else
{
/* read the line and the EOL. no error is possible. */
- g_data_input_stream_read_complete (data, found_pos,
- newline_len, result == NULL);
+ g_data_input_stream_read_complete (task, found_pos, newline_len);
}
}
@@ -1074,14 +1067,7 @@ g_data_input_stream_read_data_free (gpointer user_data)
{
GDataInputStreamReadData *data = user_data;
- /* we don't hold a ref to ->simple because it keeps a ref to us.
- * we are called because it is being finalized.
- */
-
g_free (data->stop_chars);
- if (data->cancellable)
- g_object_unref (data->cancellable);
- g_free (data->line);
g_slice_free (GDataInputStreamReadData, data);
}
@@ -1092,30 +1078,23 @@ g_data_input_stream_read_async (GDataInputStream *stream,
gint io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
- gpointer user_data,
- gpointer source_tag)
+ gpointer user_data)
{
GDataInputStreamReadData *data;
+ GTask *task;
- data = g_slice_new (GDataInputStreamReadData);
- data->stream = stream;
- if (cancellable)
- g_object_ref (cancellable);
- data->cancellable = cancellable;
+ data = g_slice_new0 (GDataInputStreamReadData);
if (stop_chars_len == -1)
stop_chars_len = strlen (stop_chars);
data->stop_chars = g_memdup (stop_chars, stop_chars_len);
data->stop_chars_len = stop_chars_len;
- data->io_priority = io_priority;
data->last_saw_cr = FALSE;
- data->checked = 0;
- data->line = NULL;
-
- data->simple = g_simple_async_result_new (G_OBJECT (stream), callback,
- user_data, source_tag);
- g_simple_async_result_set_op_res_gpointer (data->simple, data,
- g_data_input_stream_read_data_free);
- g_data_input_stream_read_line_ready (NULL, NULL, data);
+
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_task_data (task, data, g_data_input_stream_read_data_free);
+ g_task_set_priority (task, io_priority);
+
+ g_data_input_stream_read_line_ready (NULL, NULL, task);
}
static gchar *
@@ -1124,22 +1103,17 @@ g_data_input_stream_read_finish (GDataInputStream *stream,
gsize *length,
GError **error)
{
- GDataInputStreamReadData *data;
- GSimpleAsyncResult *simple;
+ GTask *task = G_TASK (result);
gchar *line;
- simple = G_SIMPLE_ASYNC_RESULT (result);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return NULL;
-
- data = g_simple_async_result_get_op_res_gpointer (simple);
-
- line = data->line;
- data->line = NULL;
+ line = g_task_propagate_pointer (task, error);
if (length && line)
- *length = data->length;
+ {
+ GDataInputStreamReadData *data = g_task_get_task_data (task);
+
+ *length = data->length;
+ }
return line;
}
@@ -1173,8 +1147,7 @@ g_data_input_stream_read_line_async (GDataInputStream *stream,
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
g_data_input_stream_read_async (stream, NULL, 0, io_priority,
- cancellable, callback, user_data,
- g_data_input_stream_read_line_async);
+ cancellable, callback, user_data);
}
/**
@@ -1218,8 +1191,7 @@ g_data_input_stream_read_until_async (GDataInputStream *stream,
g_return_if_fail (stop_chars != NULL);
g_data_input_stream_read_async (stream, stop_chars, -1, io_priority,
- cancellable, callback, user_data,
- g_data_input_stream_read_until_async);
+ cancellable, callback, user_data);
}
/**
@@ -1249,9 +1221,7 @@ g_data_input_stream_read_line_finish (GDataInputStream *stream,
gsize *length,
GError **error)
{
- g_return_val_if_fail (
- g_simple_async_result_is_valid (result, G_OBJECT (stream),
- g_data_input_stream_read_line_async), NULL);
+ g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
return g_data_input_stream_read_finish (stream, result, length, error);
}
@@ -1321,9 +1291,7 @@ g_data_input_stream_read_until_finish (GDataInputStream *stream,
gsize *length,
GError **error)
{
- g_return_val_if_fail (
- g_simple_async_result_is_valid (result, G_OBJECT (stream),
- g_data_input_stream_read_until_async), NULL);
+ g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
return g_data_input_stream_read_finish (stream, result, length, error);
}
@@ -1463,8 +1431,7 @@ g_data_input_stream_read_upto_async (GDataInputStream *stream,
g_return_if_fail (stop_chars != NULL);
g_data_input_stream_read_async (stream, stop_chars, stop_chars_len, io_priority,
- cancellable, callback, user_data,
- g_data_input_stream_read_upto_async);
+ cancellable, callback, user_data);
}
/**
@@ -1494,9 +1461,7 @@ g_data_input_stream_read_upto_finish (GDataInputStream *stream,
gsize *length,
GError **error)
{
- g_return_val_if_fail (
- g_simple_async_result_is_valid (result, G_OBJECT (stream),
- g_data_input_stream_read_upto_async), NULL);
+ g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
return g_data_input_stream_read_finish (stream, result, length, error);
}
diff --git a/gio/ginputstream.c b/gio/ginputstream.c
index 7ad7d6f..7b0ec39 100644
--- a/gio/ginputstream.c
+++ b/gio/ginputstream.c
@@ -28,7 +28,6 @@
#include "gseekable.h"
#include "gcancellable.h"
#include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
#include "gioerror.h"
#include "gpollableinputstream.h"
@@ -589,7 +588,6 @@ g_input_stream_read_async (GInputStream *stream,
gpointer user_data)
{
GInputStreamClass *class;
- GSimpleAsyncResult *simple;
GError *error = NULL;
g_return_if_fail (G_IS_INPUT_STREAM (stream));
@@ -597,32 +595,30 @@ g_input_stream_read_async (GInputStream *stream,
if (count == 0)
{
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- user_data,
- g_input_stream_read_async);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ GTask *task;
+
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_input_stream_read_async);
+ g_task_return_int (task, 0);
+ g_object_unref (task);
return;
}
if (((gssize) count) < 0)
{
- g_simple_async_report_error_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- _("Too large count value passed to %s"),
- G_STRFUNC);
+ g_task_report_new_error (stream, callback, user_data,
+ g_input_stream_read_async,
+ G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ _("Too large count value passed to %s"),
+ G_STRFUNC);
return;
}
if (!g_input_stream_set_pending (stream, &error))
{
- g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- error);
+ g_task_report_error (stream, callback, user_data,
+ g_input_stream_read_async,
+ error);
return;
}
@@ -657,10 +653,7 @@ g_input_stream_read_finish (GInputStream *stream,
if (g_async_result_legacy_propagate_error (result, error))
return -1;
else if (g_async_result_is_tagged (result, g_input_stream_read_async))
- {
- /* Special case read of 0 bytes */
- return 0;
- }
+ return g_task_propagate_int (G_TASK (result), error);
class = G_INPUT_STREAM_GET_CLASS (stream);
return class->read_finish (stream, result, error);
@@ -671,8 +664,8 @@ read_bytes_callback (GObject *stream,
GAsyncResult *result,
gpointer user_data)
{
- GSimpleAsyncResult *simple = user_data;
- guchar *buf = g_simple_async_result_get_op_res_gpointer (simple);
+ GTask *task = user_data;
+ guchar *buf = g_task_get_task_data (task);
GError *error = NULL;
gssize nread;
GBytes *bytes = NULL;
@@ -682,7 +675,7 @@ read_bytes_callback (GObject *stream,
if (nread == -1)
{
g_free (buf);
- g_simple_async_result_take_error (simple, error);
+ g_task_return_error (task, error);
}
else if (nread == 0)
{
@@ -693,12 +686,9 @@ read_bytes_callback (GObject *stream,
bytes = g_bytes_new_take (buf, nread);
if (bytes)
- {
- g_simple_async_result_set_op_res_gpointer (simple, bytes,
- (GDestroyNotify)g_bytes_unref);
- }
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_pointer (task, bytes, (GDestroyNotify)g_bytes_unref);
+
+ g_object_unref (task);
}
/**
@@ -740,18 +730,16 @@ g_input_stream_read_bytes_async (GInputStream *stream,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *simple;
+ GTask *task;
guchar *buf;
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback, user_data,
- g_input_stream_read_bytes_async);
+ task = g_task_new (stream, cancellable, callback, user_data);
buf = g_malloc (count);
- g_simple_async_result_set_op_res_gpointer (simple, buf, NULL);
+ g_task_set_task_data (task, buf, NULL);
g_input_stream_read_async (stream, buf, count,
io_priority, cancellable,
- read_bytes_callback, simple);
+ read_bytes_callback, task);
}
/**
@@ -770,15 +758,10 @@ g_input_stream_read_bytes_finish (GInputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
-
g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL);
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (stream), g_input_stream_read_bytes_async), NULL);
+ g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
- simple = G_SIMPLE_ASYNC_RESULT (result);
- if (g_simple_async_result_propagate_error (simple, error))
- return NULL;
- return g_bytes_ref (g_simple_async_result_get_op_res_gpointer (simple));
+ return g_task_propagate_pointer (G_TASK (result), error);
}
/**
@@ -824,40 +807,36 @@ g_input_stream_skip_async (GInputStream *stream,
gpointer user_data)
{
GInputStreamClass *class;
- GSimpleAsyncResult *simple;
GError *error = NULL;
g_return_if_fail (G_IS_INPUT_STREAM (stream));
if (count == 0)
{
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- user_data,
- g_input_stream_skip_async);
+ GTask *task;
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_input_stream_skip_async);
+ g_task_return_int (task, 0);
+ g_object_unref (task);
return;
}
if (((gssize) count) < 0)
{
- g_simple_async_report_error_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- _("Too large count value passed to %s"),
- G_STRFUNC);
+ g_task_report_new_error (stream, callback, user_data,
+ g_input_stream_skip_async,
+ G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ _("Too large count value passed to %s"),
+ G_STRFUNC);
return;
}
if (!g_input_stream_set_pending (stream, &error))
{
- g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- error);
+ g_task_report_error (stream, callback, user_data,
+ g_input_stream_skip_async,
+ error);
return;
}
@@ -892,10 +871,7 @@ g_input_stream_skip_finish (GInputStream *stream,
if (g_async_result_legacy_propagate_error (result, error))
return -1;
else if (g_async_result_is_tagged (result, g_input_stream_skip_async))
- {
- /* Special case skip of 0 bytes */
- return 0;
- }
+ return g_task_propagate_int (G_TASK (result), error);
class = G_INPUT_STREAM_GET_CLASS (stream);
return class->skip_finish (stream, result, error);
@@ -929,29 +905,26 @@ g_input_stream_close_async (GInputStream *stream,
gpointer user_data)
{
GInputStreamClass *class;
- GSimpleAsyncResult *simple;
GError *error = NULL;
g_return_if_fail (G_IS_INPUT_STREAM (stream));
if (stream->priv->closed)
{
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- user_data,
- g_input_stream_close_async);
+ GTask *task;
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_input_stream_close_async);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
return;
}
if (!g_input_stream_set_pending (stream, &error))
{
- g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- error);
+ g_task_report_error (stream, callback, user_data,
+ g_input_stream_close_async,
+ error);
return;
}
@@ -986,10 +959,7 @@ g_input_stream_close_finish (GInputStream *stream,
if (g_async_result_legacy_propagate_error (result, error))
return FALSE;
else if (g_async_result_is_tagged (result, g_input_stream_close_async))
- {
- /* Special case already closed */
- return TRUE;
- }
+ return g_task_propagate_boolean (G_TASK (result), error);
class = G_INPUT_STREAM_GET_CLASS (stream);
return class->close_finish (stream, result, error);
@@ -1084,95 +1054,86 @@ g_input_stream_clear_pending (GInputStream *stream)
********************************************/
typedef struct {
- void *buffer;
- gsize count_requested;
- gssize count_read;
-
- GCancellable *cancellable;
- gint io_priority;
- gboolean need_idle;
+ void *buffer;
+ gsize count;
} ReadData;
static void
free_read_data (ReadData *op)
{
- if (op->cancellable)
- g_object_unref (op->cancellable);
g_slice_free (ReadData, op);
}
static void
-read_async_thread (GSimpleAsyncResult *res,
- GObject *object,
- GCancellable *cancellable)
+read_async_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
- ReadData *op;
+ GInputStream *stream = source_object;
+ ReadData *op = task_data;
GInputStreamClass *class;
GError *error = NULL;
+ gssize nread;
- op = g_simple_async_result_get_op_res_gpointer (res);
-
- class = G_INPUT_STREAM_GET_CLASS (object);
+ class = G_INPUT_STREAM_GET_CLASS (stream);
- op->count_read = class->read_fn (G_INPUT_STREAM (object),
- op->buffer, op->count_requested,
- cancellable, &error);
- if (op->count_read == -1)
- g_simple_async_result_take_error (res, error);
+ nread = class->read_fn (stream,
+ op->buffer, op->count,
+ g_task_get_cancellable (task),
+ &error);
+ if (nread == -1)
+ g_task_return_error (task, error);
+ else
+ g_task_return_int (task, nread);
}
static void read_async_pollable (GPollableInputStream *stream,
- GSimpleAsyncResult *result);
+ GTask *task);
static gboolean
read_async_pollable_ready (GPollableInputStream *stream,
gpointer user_data)
{
- GSimpleAsyncResult *result = user_data;
+ GTask *task = user_data;
- read_async_pollable (stream, result);
+ read_async_pollable (stream, task);
return FALSE;
}
static void
read_async_pollable (GPollableInputStream *stream,
- GSimpleAsyncResult *result)
+ GTask *task)
{
+ ReadData *op = g_task_get_task_data (task);
GError *error = NULL;
- ReadData *op = g_simple_async_result_get_op_res_gpointer (result);
+ gssize nread;
- if (g_cancellable_set_error_if_cancelled (op->cancellable, &error))
- op->count_read = -1;
- else
- {
- op->count_read = G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)->
- read_nonblocking (stream, op->buffer, op->count_requested, &error);
- }
+ if (g_task_return_error_if_cancelled (task))
+ return;
+
+ nread = G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)->
+ read_nonblocking (stream, op->buffer, op->count, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
{
GSource *source;
g_error_free (error);
- op->need_idle = FALSE;
-
- source = g_pollable_input_stream_create_source (stream, op->cancellable);
- g_source_set_callback (source,
- (GSourceFunc) read_async_pollable_ready,
- g_object_ref (result), g_object_unref);
- g_source_set_priority (source, op->io_priority);
- g_source_attach (source, g_main_context_get_thread_default ());
+
+ source = g_pollable_input_stream_create_source (stream,
+ g_task_get_cancellable (task));
+ g_task_attach_source (task, source,
+ (GSourceFunc) read_async_pollable_ready);
g_source_unref (source);
return;
}
- if (op->count_read == -1)
- g_simple_async_result_take_error (result, error);
-
- if (op->need_idle)
- g_simple_async_result_complete_in_idle (result);
+ if (nread == -1)
+ g_task_return_error (task, error);
else
- g_simple_async_result_complete (result);
+ g_task_return_int (task, nread);
+ /* g_input_stream_real_read_async() unrefs task */
}
static void
@@ -1184,24 +1145,22 @@ g_input_stream_real_read_async (GInputStream *stream,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *res;
+ GTask *task;
ReadData *op;
op = g_slice_new0 (ReadData);
- res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_input_stream_real_read_async);
- g_simple_async_result_set_op_res_gpointer (res, op, (GDestroyNotify) free_read_data);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_task_data (task, op, (GDestroyNotify) free_read_data);
+ g_task_set_priority (task, io_priority);
op->buffer = buffer;
- op->count_requested = count;
- op->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- op->io_priority = io_priority;
- op->need_idle = TRUE;
+ op->count = count;
if (G_IS_POLLABLE_INPUT_STREAM (stream) &&
g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (stream)))
- read_async_pollable (G_POLLABLE_INPUT_STREAM (stream), res);
+ read_async_pollable (G_POLLABLE_INPUT_STREAM (stream), task);
else
- g_simple_async_result_run_in_thread (res, read_async_thread, io_priority, cancellable);
- g_object_unref (res);
+ g_task_run_in_thread (task, read_async_thread);
+ g_object_unref (task);
}
static gssize
@@ -1209,50 +1168,38 @@ g_input_stream_real_read_finish (GInputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
- ReadData *op;
-
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) ==
- g_input_stream_real_read_async);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return -1;
-
- op = g_simple_async_result_get_op_res_gpointer (simple);
+ g_return_val_if_fail (g_task_is_valid (result, stream), -1);
- return op->count_read;
+ return g_task_propagate_int (G_TASK (result), error);
}
-typedef struct {
- gsize count_requested;
- gssize count_skipped;
-} SkipData;
-
static void
-skip_async_thread (GSimpleAsyncResult *res,
- GObject *object,
- GCancellable *cancellable)
+skip_async_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
- SkipData *op;
+ GInputStream *stream = source_object;
+ gsize count = GPOINTER_TO_SIZE (task_data);
GInputStreamClass *class;
GError *error = NULL;
-
- class = G_INPUT_STREAM_GET_CLASS (object);
- op = g_simple_async_result_get_op_res_gpointer (res);
- op->count_skipped = class->skip (G_INPUT_STREAM (object),
- op->count_requested,
- cancellable, &error);
- if (op->count_skipped == -1)
- g_simple_async_result_take_error (res, error);
+ gssize ret;
+
+ class = G_INPUT_STREAM_GET_CLASS (stream);
+ ret = class->skip (stream, count,
+ g_task_get_cancellable (task),
+ &error);
+ if (ret == -1)
+ g_task_return_error (task, error);
+ else
+ g_task_return_int (task, ret);
}
typedef struct {
char buffer[8192];
gsize count;
gsize count_skipped;
- int io_prio;
- GCancellable *cancellable;
gpointer user_data;
GAsyncReadyCallback callback;
} SkipFallbackAsyncData;
@@ -1263,9 +1210,8 @@ skip_callback_wrapper (GObject *source_object,
gpointer user_data)
{
GInputStreamClass *class;
- SkipFallbackAsyncData *data = user_data;
- SkipData *op;
- GSimpleAsyncResult *simple;
+ GTask *task = user_data;
+ SkipFallbackAsyncData *data = g_task_get_task_data (task);
GError *error = NULL;
gssize ret;
@@ -1279,35 +1225,28 @@ skip_callback_wrapper (GObject *source_object,
if (data->count > 0)
{
class = G_INPUT_STREAM_GET_CLASS (source_object);
- class->read_async (G_INPUT_STREAM (source_object), data->buffer, MIN (8192, data->count), data->io_prio, data->cancellable,
+ class->read_async (G_INPUT_STREAM (source_object),
+ data->buffer, MIN (8192, data->count),
+ g_task_get_priority (task),
+ g_task_get_cancellable (task),
skip_callback_wrapper, data);
return;
}
}
- op = g_new0 (SkipData, 1);
- op->count_skipped = data->count_skipped;
- simple = g_simple_async_result_new (source_object,
- data->callback, data->user_data,
- g_input_stream_real_skip_async);
-
- g_simple_async_result_set_op_res_gpointer (simple, op, g_free);
-
- if (ret == -1)
+ if (ret == -1 &&
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
+ data->count_skipped)
{
- if (data->count_skipped &&
- g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- /* No error, return partial read */
- g_error_free (error);
- else
- g_simple_async_result_take_error (simple, error);
+ /* No error, return partial read */
+ g_clear_error (&error);
}
- /* Complete immediately, not in idle, since we're already in a mainloop callout */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-
- g_free (data);
+ if (error)
+ g_task_return_error (task, error);
+ else
+ g_task_return_int (task, data->count_skipped);
+ g_object_unref (task);
}
static void
@@ -1319,28 +1258,23 @@ g_input_stream_real_skip_async (GInputStream *stream,
gpointer user_data)
{
GInputStreamClass *class;
- SkipData *op;
SkipFallbackAsyncData *data;
- GSimpleAsyncResult *res;
+ GTask *task;
class = G_INPUT_STREAM_GET_CLASS (stream);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_priority (task, io_priority);
+
if (class->read_async == g_input_stream_real_read_async)
{
/* Read is thread-using async fallback.
* Make skip use threads too, so that we can use a possible sync skip
* implementation. */
- op = g_new0 (SkipData, 1);
-
- res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
- g_input_stream_real_skip_async);
-
- g_simple_async_result_set_op_res_gpointer (res, op, g_free);
+ g_task_set_task_data (task, GSIZE_TO_POINTER (count), NULL);
- op->count_requested = count;
-
- g_simple_async_result_run_in_thread (res, skip_async_thread, io_priority, cancellable);
- g_object_unref (res);
+ g_task_run_in_thread (task, skip_async_thread);
+ g_object_unref (task);
}
else
{
@@ -1350,10 +1284,10 @@ g_input_stream_real_skip_async (GInputStream *stream,
data = g_new (SkipFallbackAsyncData, 1);
data->count = count;
data->count_skipped = 0;
- data->io_prio = io_priority;
- data->cancellable = cancellable;
data->callback = callback;
data->user_data = user_data;
+ g_task_set_task_data (task, data, g_free);
+ g_task_set_check_cancellable (task, FALSE);
class->read_async (stream, data->buffer, MIN (8192, count), io_priority, cancellable,
skip_callback_wrapper, data);
}
@@ -1365,39 +1299,36 @@ g_input_stream_real_skip_finish (GInputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
- SkipData *op;
-
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_input_stream_real_skip_async);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return -1;
+ g_return_val_if_fail (g_task_is_valid (result, stream), -1);
- op = g_simple_async_result_get_op_res_gpointer (simple);
- return op->count_skipped;
+ return g_task_propagate_int (G_TASK (result), error);
}
static void
-close_async_thread (GSimpleAsyncResult *res,
- GObject *object,
- GCancellable *cancellable)
+close_async_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
+ GInputStream *stream = source_object;
GInputStreamClass *class;
GError *error = NULL;
gboolean result;
- /* Auto handling of cancelation disabled, and ignore
- cancellation, since we want to close things anyway, although
- possibly in a quick-n-dirty way. At least we never want to leak
- open handles */
-
- class = G_INPUT_STREAM_GET_CLASS (object);
+ class = G_INPUT_STREAM_GET_CLASS (stream);
if (class->close_fn)
{
- result = class->close_fn (G_INPUT_STREAM (object), cancellable, &error);
+ result = class->close_fn (stream,
+ g_task_get_cancellable (task),
+ &error);
if (!result)
- g_simple_async_result_take_error (res, error);
+ {
+ g_task_return_error (task, error);
+ return;
+ }
}
+
+ g_task_return_boolean (task, TRUE);
}
static void
@@ -1407,20 +1338,14 @@ g_input_stream_real_close_async (GInputStream *stream,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *res;
-
- res = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- user_data,
- g_input_stream_real_close_async);
+ GTask *task;
- g_simple_async_result_set_handle_cancellation (res, FALSE);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_check_cancellable (task, FALSE);
+ g_task_set_priority (task, io_priority);
- g_simple_async_result_run_in_thread (res,
- close_async_thread,
- io_priority,
- cancellable);
- g_object_unref (res);
+ g_task_run_in_thread (task, close_async_thread);
+ g_object_unref (task);
}
static gboolean
@@ -1428,12 +1353,7 @@ g_input_stream_real_close_finish (GInputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_input_stream_real_close_async);
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
-
- return TRUE;
+ return g_task_propagate_boolean (G_TASK (result), error);
}
diff --git a/gio/giostream.c b/gio/giostream.c
index 574eea3..1f882e6 100644
--- a/gio/giostream.c
+++ b/gio/giostream.c
@@ -27,9 +27,8 @@
#include "glibintl.h"
#include "giostream.h"
-#include <gio/gsimpleasyncresult.h>
-#include <gio/gasyncresult.h>
-
+#include "gasyncresult.h"
+#include "gtask.h"
G_DEFINE_ABSTRACT_TYPE (GIOStream, g_io_stream, G_TYPE_OBJECT);
@@ -465,28 +464,26 @@ g_io_stream_close_async (GIOStream *stream,
gpointer user_data)
{
GIOStreamClass *class;
- GSimpleAsyncResult *simple;
GError *error = NULL;
g_return_if_fail (G_IS_IO_STREAM (stream));
if (stream->priv->closed)
{
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- user_data,
- g_io_stream_close_async);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ GTask *task;
+
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_io_stream_close_async);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
return;
}
if (!g_io_stream_set_pending (stream, &error))
{
- g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- error);
+ g_task_report_error (stream, callback, user_data,
+ g_io_stream_close_async,
+ error);
return;
}
@@ -523,10 +520,7 @@ g_io_stream_close_finish (GIOStream *stream,
if (g_async_result_legacy_propagate_error (result, error))
return FALSE;
else if (g_async_result_is_tagged (result, g_io_stream_close_async))
- {
- /* Special case already closed */
- return TRUE;
- }
+ return g_task_propagate_boolean (G_TASK (result), error);
class = G_IO_STREAM_GET_CLASS (stream);
return class->close_finish (stream, result, error);
@@ -534,25 +528,30 @@ g_io_stream_close_finish (GIOStream *stream,
static void
-close_async_thread (GSimpleAsyncResult *res,
- GObject *object,
- GCancellable *cancellable)
+close_async_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
+ GIOStream *stream = source_object;
GIOStreamClass *class;
GError *error = NULL;
gboolean result;
- /* Auto handling of cancelation disabled, and ignore cancellation,
- * since we want to close things anyway, although possibly in a
- * quick-n-dirty way. At least we never want to leak open handles
- */
- class = G_IO_STREAM_GET_CLASS (object);
+ class = G_IO_STREAM_GET_CLASS (stream);
if (class->close_fn)
{
- result = class->close_fn (G_IO_STREAM (object), cancellable, &error);
+ result = class->close_fn (stream,
+ g_task_get_cancellable (task),
+ &error);
if (!result)
- g_simple_async_result_take_error (res, error);
+ {
+ g_task_return_error (task, error);
+ return;
+ }
}
+
+ g_task_return_boolean (task, TRUE);
}
static void
@@ -562,20 +561,14 @@ g_io_stream_real_close_async (GIOStream *stream,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *res;
-
- res = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- user_data,
- g_io_stream_real_close_async);
-
- g_simple_async_result_set_handle_cancellation (res, FALSE);
-
- g_simple_async_result_run_in_thread (res,
- close_async_thread,
- io_priority,
- cancellable);
- g_object_unref (res);
+ GTask *task;
+
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_check_cancellable (task, FALSE);
+ g_task_set_priority (task, io_priority);
+
+ g_task_run_in_thread (task, close_async_thread);
+ g_object_unref (task);
}
static gboolean
@@ -583,15 +576,9 @@ g_io_stream_real_close_finish (GIOStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) ==
- g_io_stream_real_close_async);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
- return TRUE;
+ return g_task_propagate_boolean (G_TASK (result), error);
}
typedef struct
@@ -622,16 +609,20 @@ splice_context_free (SpliceContext *ctx)
}
static void
-splice_complete (GSimpleAsyncResult *simple,
- SpliceContext *ctx)
+splice_complete (GTask *task,
+ SpliceContext *ctx)
{
if (ctx->cancelled_id != 0)
g_cancellable_disconnect (ctx->cancellable, ctx->cancelled_id);
ctx->cancelled_id = 0;
if (ctx->error != NULL)
- g_simple_async_result_set_from_error (simple, ctx->error);
- g_simple_async_result_complete (simple);
+ {
+ g_task_return_error (task, ctx->error);
+ ctx->error = NULL;
+ }
+ else
+ g_task_return_boolean (task, TRUE);
}
static void
@@ -639,13 +630,12 @@ splice_close_cb (GObject *iostream,
GAsyncResult *res,
gpointer user_data)
{
- GSimpleAsyncResult *simple = user_data;
- SpliceContext *ctx;
+ GTask *task = user_data;
+ SpliceContext *ctx = g_task_get_task_data (task);
GError *error = NULL;
g_io_stream_close_finish (G_IO_STREAM (iostream), res, &error);
- ctx = g_simple_async_result_get_op_res_gpointer (simple);
ctx->completed++;
/* Keep the first error that occurred */
@@ -656,9 +646,9 @@ splice_close_cb (GObject *iostream,
/* If all operations are done, complete now */
if (ctx->completed == 4)
- splice_complete (simple, ctx);
+ splice_complete (task, ctx);
- g_object_unref (simple);
+ g_object_unref (task);
}
static void
@@ -666,13 +656,12 @@ splice_cb (GObject *ostream,
GAsyncResult *res,
gpointer user_data)
{
- GSimpleAsyncResult *simple = user_data;
- SpliceContext *ctx;
+ GTask *task = user_data;
+ SpliceContext *ctx = g_task_get_task_data (task);
GError *error = NULL;
g_output_stream_splice_finish (G_OUTPUT_STREAM (ostream), res, &error);
- ctx = g_simple_async_result_get_op_res_gpointer (simple);
ctx->completed++;
/* ignore cancellation error if it was not requested by the user */
@@ -706,32 +695,40 @@ splice_cb (GObject *ostream,
/* Close the IO streams if needed */
if ((ctx->flags & G_IO_STREAM_SPLICE_CLOSE_STREAM1) != 0)
- g_io_stream_close_async (ctx->stream1, ctx->io_priority,
- ctx->op1_cancellable, splice_close_cb, g_object_ref (simple));
+ {
+ g_io_stream_close_async (ctx->stream1,
+ g_task_get_priority (task),
+ ctx->op1_cancellable,
+ splice_close_cb, g_object_ref (task));
+ }
else
ctx->completed++;
if ((ctx->flags & G_IO_STREAM_SPLICE_CLOSE_STREAM2) != 0)
- g_io_stream_close_async (ctx->stream2, ctx->io_priority,
- ctx->op2_cancellable, splice_close_cb, g_object_ref (simple));
+ {
+ g_io_stream_close_async (ctx->stream2,
+ g_task_get_priority (task),
+ ctx->op2_cancellable,
+ splice_close_cb, g_object_ref (task));
+ }
else
ctx->completed++;
/* If all operations are done, complete now */
if (ctx->completed == 4)
- splice_complete (simple, ctx);
+ splice_complete (task, ctx);
}
- g_object_unref (simple);
+ g_object_unref (task);
}
static void
-splice_cancelled_cb (GCancellable *cancellable,
- GSimpleAsyncResult *simple)
+splice_cancelled_cb (GCancellable *cancellable,
+ GTask *task)
{
SpliceContext *ctx;
- ctx = g_simple_async_result_get_op_res_gpointer (simple);
+ ctx = g_task_get_task_data (task);
g_cancellable_cancel (ctx->op1_cancellable);
g_cancellable_cancel (ctx->op2_cancellable);
}
@@ -765,16 +762,17 @@ g_io_stream_splice_async (GIOStream *stream1,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *simple;
+ GTask *task;
SpliceContext *ctx;
GInputStream *istream;
GOutputStream *ostream;
if (cancellable != NULL && g_cancellable_is_cancelled (cancellable))
{
- g_simple_async_report_error_in_idle (NULL, callback,
- user_data, G_IO_ERROR, G_IO_ERROR_CANCELLED,
- "Operation has been cancelled");
+ g_task_report_new_error (NULL, callback, user_data,
+ g_io_stream_splice_async,
+ G_IO_ERROR, G_IO_ERROR_CANCELLED,
+ "Operation has been cancelled");
return;
}
@@ -782,21 +780,18 @@ g_io_stream_splice_async (GIOStream *stream1,
ctx->stream1 = g_object_ref (stream1);
ctx->stream2 = g_object_ref (stream2);
ctx->flags = flags;
- ctx->io_priority = io_priority;
ctx->op1_cancellable = g_cancellable_new ();
ctx->op2_cancellable = g_cancellable_new ();
ctx->completed = 0;
- simple = g_simple_async_result_new (NULL, callback, user_data,
- g_io_stream_splice_finish);
- g_simple_async_result_set_op_res_gpointer (simple, ctx,
- (GDestroyNotify) splice_context_free);
+ task = g_task_new (NULL, cancellable, callback, user_data);
+ g_task_set_task_data (task, ctx, (GDestroyNotify) splice_context_free);
if (cancellable != NULL)
{
ctx->cancellable = g_object_ref (cancellable);
ctx->cancelled_id = g_cancellable_connect (cancellable,
- G_CALLBACK (splice_cancelled_cb), g_object_ref (simple),
+ G_CALLBACK (splice_cancelled_cb), g_object_ref (task),
g_object_unref);
}
@@ -804,15 +799,15 @@ g_io_stream_splice_async (GIOStream *stream1,
ostream = g_io_stream_get_output_stream (stream2);
g_output_stream_splice_async (ostream, istream, G_OUTPUT_STREAM_SPLICE_NONE,
io_priority, ctx->op1_cancellable, splice_cb,
- g_object_ref (simple));
+ g_object_ref (task));
istream = g_io_stream_get_input_stream (stream2);
ostream = g_io_stream_get_output_stream (stream1);
g_output_stream_splice_async (ostream, istream, G_OUTPUT_STREAM_SPLICE_NONE,
io_priority, ctx->op2_cancellable, splice_cb,
- g_object_ref (simple));
+ g_object_ref (task));
- g_object_unref (simple);
+ g_object_unref (task);
}
/**
@@ -831,17 +826,7 @@ gboolean
g_io_stream_splice_finish (GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
+ g_return_val_if_fail (g_task_is_valid (result, NULL), FALSE);
- g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
- g_io_stream_splice_finish), FALSE);
-
- return TRUE;
+ return g_task_propagate_boolean (G_TASK (result), error);
}
diff --git a/gio/gmemoryinputstream.c b/gio/gmemoryinputstream.c
index 630def2..f058d9d 100644
--- a/gio/gmemoryinputstream.c
+++ b/gio/gmemoryinputstream.c
@@ -26,7 +26,7 @@
#include "ginputstream.h"
#include "gseekable.h"
#include "string.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
#include "gioerror.h"
#include "glibintl.h"
@@ -377,17 +377,13 @@ g_memory_input_stream_skip_async (GInputStream *stream,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *simple;
+ GTask *task;
gssize nskipped;
nskipped = g_input_stream_skip (stream, count, cancellable, NULL);
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- user_data,
- g_memory_input_stream_skip_async);
- g_simple_async_result_set_op_res_gssize (simple, nskipped);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_return_int (task, nskipped);
+ g_object_unref (task);
}
static gssize
@@ -395,14 +391,9 @@ g_memory_input_stream_skip_finish (GInputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
- gssize nskipped;
+ g_return_val_if_fail (g_task_is_valid (result, stream), -1);
- simple = G_SIMPLE_ASYNC_RESULT (result);
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_memory_input_stream_skip_async);
-
- nskipped = g_simple_async_result_get_op_res_gssize (simple);
- return nskipped;
+ return g_task_propagate_int (G_TASK (result), error);
}
static void
@@ -412,14 +403,11 @@ g_memory_input_stream_close_async (GInputStream *stream,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *simple;
-
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- user_data,
- g_memory_input_stream_close_async);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ GTask *task;
+
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
static gboolean
diff --git a/gio/gmemoryoutputstream.c b/gio/gmemoryoutputstream.c
index 378bf3c..9b46044 100644
--- a/gio/gmemoryoutputstream.c
+++ b/gio/gmemoryoutputstream.c
@@ -27,7 +27,7 @@
#include "goutputstream.h"
#include "gpollableoutputstream.h"
#include "gseekable.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
#include "gioerror.h"
#include "string.h"
#include "glibintl.h"
@@ -651,19 +651,15 @@ g_memory_output_stream_close_async (GOutputStream *stream,
GAsyncReadyCallback callback,
gpointer data)
{
- GSimpleAsyncResult *simple;
-
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- data,
- g_memory_output_stream_close_async);
+ GTask *task;
+ task = g_task_new (stream, cancellable, callback, data);
/* will always return TRUE */
g_memory_output_stream_close (stream, cancellable, NULL);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
static gboolean
@@ -671,14 +667,9 @@ g_memory_output_stream_close_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
+ g_return_val_if_fail (g_task_is_valid (result, stream), -1);
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) ==
- g_memory_output_stream_close_async);
-
- return TRUE;
+ return g_task_propagate_boolean (G_TASK (result), error);
}
static goffset
diff --git a/gio/goutputstream.c b/gio/goutputstream.c
index aaf82f5..e0b22bd 100644
--- a/gio/goutputstream.c
+++ b/gio/goutputstream.c
@@ -24,7 +24,7 @@
#include "goutputstream.h"
#include "gcancellable.h"
#include "gasyncresult.h"
-#include "gsimpleasyncresult.h"
+#include "gtask.h"
#include "ginputstream.h"
#include "gioerror.h"
#include "glibintl.h"
@@ -631,96 +631,31 @@ g_output_stream_close (GOutputStream *stream,
}
static void
-async_ready_callback_wrapper (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GOutputStream *stream = G_OUTPUT_STREAM (source_object);
-
- g_output_stream_clear_pending (stream);
- if (stream->priv->outstanding_callback)
- (*stream->priv->outstanding_callback) (source_object, res, user_data);
- g_object_unref (stream);
-}
-
-typedef struct {
- gint io_priority;
- GCancellable *cancellable;
- GError *flush_error;
- gpointer user_data;
-} CloseUserData;
-
-static void
-async_ready_close_callback_wrapper (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GOutputStream *stream = G_OUTPUT_STREAM (source_object);
- CloseUserData *data = user_data;
-
- stream->priv->closing = FALSE;
- stream->priv->closed = TRUE;
-
- g_output_stream_clear_pending (stream);
-
- if (stream->priv->outstanding_callback)
- {
- if (data->flush_error != NULL)
- {
- GSimpleAsyncResult *err;
-
- err = g_simple_async_result_new_take_error (source_object,
- stream->priv->outstanding_callback,
- data->user_data,
- data->flush_error);
- data->flush_error = NULL;
-
- (*stream->priv->outstanding_callback) (source_object,
- G_ASYNC_RESULT (err),
- data->user_data);
- g_object_unref (err);
- }
- else
- {
- (*stream->priv->outstanding_callback) (source_object,
- res,
- data->user_data);
- }
- }
-
- g_object_unref (stream);
-
- if (data->cancellable)
- g_object_unref (data->cancellable);
-
- if (data->flush_error)
- g_error_free (data->flush_error);
-
- g_slice_free (CloseUserData, data);
-}
-
-static void
-async_ready_close_flushed_callback_wrapper (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
+async_ready_write_callback_wrapper (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
GOutputStream *stream = G_OUTPUT_STREAM (source_object);
GOutputStreamClass *class;
- CloseUserData *data = user_data;
- GSimpleAsyncResult *simple;
+ GTask *task = user_data;
+ gssize nwrote;
+ GError *error = NULL;
- /* propagate the possible error */
- if (G_IS_SIMPLE_ASYNC_RESULT (res))
+ g_output_stream_clear_pending (stream);
+
+ if (g_async_result_legacy_propagate_error (res, &error))
+ nwrote = -1;
+ else
{
- simple = G_SIMPLE_ASYNC_RESULT (res);
- g_simple_async_result_propagate_error (simple, &data->flush_error);
+ class = G_OUTPUT_STREAM_GET_CLASS (stream);
+ nwrote = class->write_finish (stream, res, &error);
}
- class = G_OUTPUT_STREAM_GET_CLASS (stream);
-
- /* we still close, even if there was a flush error */
- class->close_async (stream, data->io_priority, data->cancellable,
- async_ready_close_callback_wrapper, user_data);
+ if (nwrote >= 0)
+ g_task_return_int (task, nwrote);
+ else
+ g_task_return_error (task, error);
+ g_object_unref (task);
}
/**
@@ -774,49 +709,43 @@ g_output_stream_write_async (GOutputStream *stream,
gpointer user_data)
{
GOutputStreamClass *class;
- GSimpleAsyncResult *simple;
GError *error = NULL;
+ GTask *task;
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
g_return_if_fail (buffer != NULL);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_output_stream_write_async);
+ g_task_set_priority (task, io_priority);
+
if (count == 0)
{
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- user_data,
- g_output_stream_write_async);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ g_task_return_int (task, 0);
+ g_object_unref (task);
return;
}
if (((gssize) count) < 0)
{
- g_simple_async_report_error_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- _("Too large count value passed to %s"),
- G_STRFUNC);
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ _("Too large count value passed to %s"),
+ G_STRFUNC);
+ g_object_unref (task);
return;
}
if (!g_output_stream_set_pending (stream, &error))
{
- g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- error);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
class = G_OUTPUT_STREAM_GET_CLASS (stream);
- stream->priv->outstanding_callback = callback;
- g_object_ref (stream);
class->write_async (stream, buffer, count, io_priority, cancellable,
- async_ready_callback_wrapper, user_data);
+ async_ready_write_callback_wrapper, task);
}
/**
@@ -835,21 +764,14 @@ g_output_stream_write_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- GOutputStreamClass *class;
-
- g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
+ g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
+ g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_write_async), FALSE);
- if (g_async_result_legacy_propagate_error (result, error))
- return -1;
- else if (g_async_result_is_tagged (result, g_output_stream_write_async))
- {
- /* Special case writes of 0 bytes */
- return 0;
- }
-
- class = G_OUTPUT_STREAM_GET_CLASS (stream);
- return class->write_finish (stream, result, error);
+ /* @result is always the GTask created by g_output_stream_write_async();
+ * we called class->write_finish() from async_ready_write_callback_wrapper.
+ */
+ return g_task_propagate_int (G_TASK (result), error);
}
static void
@@ -857,18 +779,17 @@ write_bytes_callback (GObject *stream,
GAsyncResult *result,
gpointer user_data)
{
- GSimpleAsyncResult *simple = user_data;
+ GTask *task = user_data;
GError *error = NULL;
gssize nwrote;
nwrote = g_output_stream_write_finish (G_OUTPUT_STREAM (stream),
result, &error);
if (nwrote == -1)
- g_simple_async_result_take_error (simple, error);
+ g_task_return_error (task, error);
else
- g_simple_async_result_set_op_res_gssize (simple, nwrote);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ g_task_return_int (task, nwrote);
+ g_object_unref (task);
}
/**
@@ -915,24 +836,22 @@ g_output_stream_write_bytes_async (GOutputStream *stream,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *simple;
+ GTask *task;
gsize size;
gconstpointer data;
data = g_bytes_get_data (bytes, &size);
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback, user_data,
- g_output_stream_write_bytes_async);
- g_simple_async_result_set_op_res_gpointer (simple, g_bytes_ref (bytes),
- (GDestroyNotify) g_bytes_unref);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_task_data (task, g_bytes_ref (bytes),
+ (GDestroyNotify) g_bytes_unref);
g_output_stream_write_async (stream,
data, size,
io_priority,
cancellable,
write_bytes_callback,
- simple);
+ task);
}
/**
@@ -951,15 +870,10 @@ g_output_stream_write_bytes_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
-
g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (stream), g_output_stream_write_bytes_async), -1);
+ g_return_val_if_fail (g_task_is_valid (result, stream), -1);
- simple = G_SIMPLE_ASYNC_RESULT (result);
- if (g_simple_async_result_propagate_error (simple, error))
- return -1;
- return g_simple_async_result_get_op_res_gssize (simple);
+ return g_task_propagate_int (G_TASK (result), error);
}
typedef struct {
@@ -974,16 +888,26 @@ async_ready_splice_callback_wrapper (GObject *source_object,
gpointer _data)
{
GOutputStream *stream = G_OUTPUT_STREAM (source_object);
- SpliceUserData *data = _data;
-
+ GOutputStreamClass *class;
+ GTask *task = _data;
+ gssize nspliced;
+ GError *error = NULL;
+
g_output_stream_clear_pending (stream);
- if (data->callback)
- (*data->callback) (source_object, res, data->user_data);
-
- g_object_unref (stream);
- g_object_unref (data->source);
- g_free (data);
+ if (g_async_result_legacy_propagate_error (res, &error))
+ nspliced = -1;
+ else
+ {
+ class = G_OUTPUT_STREAM_GET_CLASS (stream);
+ nspliced = class->splice_finish (stream, res, &error);
+ }
+
+ if (nspliced >= 0)
+ g_task_return_int (task, nspliced);
+ else
+ g_task_return_error (task, error);
+ g_object_unref (task);
}
/**
@@ -1014,41 +938,37 @@ g_output_stream_splice_async (GOutputStream *stream,
gpointer user_data)
{
GOutputStreamClass *class;
- SpliceUserData *data;
+ GTask *task;
GError *error = NULL;
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
g_return_if_fail (G_IS_INPUT_STREAM (source));
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_output_stream_splice_async);
+ g_task_set_priority (task, io_priority);
+ g_task_set_task_data (task, g_object_ref (source), g_object_unref);
+
if (g_input_stream_is_closed (source))
{
- g_simple_async_report_error_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_CLOSED,
- _("Source stream is already closed"));
+ g_task_return_new_error (task,
+ G_IO_ERROR, G_IO_ERROR_CLOSED,
+ _("Source stream is already closed"));
+ g_object_unref (task);
return;
}
if (!g_output_stream_set_pending (stream, &error))
{
- g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- error);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
class = G_OUTPUT_STREAM_GET_CLASS (stream);
- data = g_new0 (SpliceUserData, 1);
- data->callback = callback;
- data->user_data = user_data;
- data->source = g_object_ref (source);
-
- g_object_ref (stream);
class->splice_async (stream, source, flags, io_priority, cancellable,
- async_ready_splice_callback_wrapper, data);
+ async_ready_splice_callback_wrapper, task);
}
/**
@@ -1070,16 +990,42 @@ g_output_stream_splice_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- GOutputStreamClass *class;
+ g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
+ g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_splice_async), FALSE);
- g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
+ /* @result is always the GTask created by g_output_stream_splice_async();
+ * we called class->splice_finish() from async_ready_splice_callback_wrapper.
+ */
+ return g_task_propagate_int (G_TASK (result), error);
+}
- if (g_async_result_legacy_propagate_error (result, error))
- return -1;
+static void
+async_ready_flush_callback_wrapper (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GOutputStream *stream = G_OUTPUT_STREAM (source_object);
+ GOutputStreamClass *class;
+ GTask *task = user_data;
+ gboolean flushed;
+ GError *error = NULL;
+
+ g_output_stream_clear_pending (stream);
- class = G_OUTPUT_STREAM_GET_CLASS (stream);
- return class->splice_finish (stream, result, error);
+ if (g_async_result_legacy_propagate_error (res, &error))
+ flushed = FALSE;
+ else
+ {
+ class = G_OUTPUT_STREAM_GET_CLASS (stream);
+ flushed = class->flush_finish (stream, res, &error);
+ }
+
+ if (flushed)
+ g_task_return_boolean (task, TRUE);
+ else
+ g_task_return_error (task, error);
+ g_object_unref (task);
}
/**
@@ -1106,38 +1052,33 @@ g_output_stream_flush_async (GOutputStream *stream,
gpointer user_data)
{
GOutputStreamClass *class;
- GSimpleAsyncResult *simple;
+ GTask *task;
GError *error = NULL;
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_output_stream_flush_async);
+ g_task_set_priority (task, io_priority);
+
if (!g_output_stream_set_pending (stream, &error))
{
- g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- error);
+ g_task_return_error (task, error);
+ g_object_unref (task);
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),
- async_ready_callback_wrapper,
- user_data,
- g_output_stream_flush_async);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
return;
}
class->flush_async (stream, io_priority, cancellable,
- async_ready_callback_wrapper, user_data);
+ async_ready_flush_callback_wrapper, task);
}
/**
@@ -1156,23 +1097,74 @@ g_output_stream_flush_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- GOutputStreamClass *klass;
-
g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
+ g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_flush_async), FALSE);
- if (g_async_result_legacy_propagate_error (result, error))
- return FALSE;
- else if (g_async_result_is_tagged (result, g_output_stream_flush_async))
+ /* @result is always the GTask created by g_output_stream_flush_async();
+ * we called class->flush_finish() from async_ready_flush_callback_wrapper.
+ */
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+
+static void
+async_ready_close_callback_wrapper (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GOutputStream *stream = G_OUTPUT_STREAM (source_object);
+ GOutputStreamClass *class;
+ GTask *task = user_data;
+ GError *error = g_task_get_task_data (task);
+
+ stream->priv->closing = FALSE;
+ stream->priv->closed = TRUE;
+
+ if (!error && !g_async_result_legacy_propagate_error (res, &error))
{
- /* Special case default implementation */
- return 0;
+ class = G_OUTPUT_STREAM_GET_CLASS (stream);
+
+ class->close_finish (stream, res,
+ error ? NULL : &error);
}
- klass = G_OUTPUT_STREAM_GET_CLASS (stream);
- return klass->flush_finish (stream, result, error);
+ g_output_stream_clear_pending (stream);
+
+ if (error != NULL)
+ g_task_return_error (task, error);
+ else
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
+static void
+async_ready_close_flushed_callback_wrapper (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GOutputStream *stream = G_OUTPUT_STREAM (source_object);
+ GOutputStreamClass *class;
+ GTask *task = user_data;
+ GError *error = NULL;
+
+ if (!g_async_result_legacy_propagate_error (res, &error))
+ {
+ class = G_OUTPUT_STREAM_GET_CLASS (stream);
+
+ class->flush_finish (stream, res, &error);
+ }
+
+ /* propagate the possible error */
+ if (error)
+ g_task_set_task_data (task, error, NULL);
+
+ /* we still close, even if there was a flush error */
+ class->close_async (stream,
+ g_task_get_priority (task),
+ g_task_get_cancellable (task),
+ async_ready_close_callback_wrapper, task);
+}
/**
* g_output_stream_close_async:
@@ -1201,44 +1193,31 @@ g_output_stream_close_async (GOutputStream *stream,
gpointer user_data)
{
GOutputStreamClass *class;
- GSimpleAsyncResult *simple;
+ GTask *task;
GError *error = NULL;
- CloseUserData *data;
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_output_stream_close_async);
+ g_task_set_priority (task, io_priority);
+
if (stream->priv->closed)
{
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback,
- user_data,
- g_output_stream_close_async);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
return;
}
if (!g_output_stream_set_pending (stream, &error))
{
- g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- error);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
class = G_OUTPUT_STREAM_GET_CLASS (stream);
stream->priv->closing = TRUE;
- stream->priv->outstanding_callback = callback;
- g_object_ref (stream);
-
- data = g_slice_new0 (CloseUserData);
-
- if (cancellable != NULL)
- data->cancellable = g_object_ref (cancellable);
-
- data->io_priority = io_priority;
- data->user_data = user_data;
/* Call close_async directly if there is no need to flush, or if the flush
can be done sync (in the output stream async close thread) */
@@ -1247,14 +1226,14 @@ g_output_stream_close_async (GOutputStream *stream,
(class->flush == NULL || class->close_async == g_output_stream_real_close_async)))
{
class->close_async (stream, io_priority, cancellable,
- async_ready_close_callback_wrapper, data);
+ async_ready_close_callback_wrapper, task);
}
else
{
/* First do an async flush, then do the async close in the callback
wrapper (see async_ready_close_flushed_callback_wrapper) */
class->flush_async (stream, io_priority, cancellable,
- async_ready_close_flushed_callback_wrapper, data);
+ async_ready_close_flushed_callback_wrapper, task);
}
}
@@ -1274,21 +1253,14 @@ g_output_stream_close_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- GOutputStreamClass *class;
-
g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
-
- if (g_async_result_legacy_propagate_error (result, error))
- return FALSE;
- else if (g_async_result_is_tagged (result, g_output_stream_close_async))
- {
- /* Special case already closed */
- return TRUE;
- }
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
+ g_return_val_if_fail (g_async_result_is_tagged (result, g_output_stream_close_async), FALSE);
- class = G_OUTPUT_STREAM_GET_CLASS (stream);
- return class->close_finish (stream, result, error);
+ /* @result is always the GTask created by g_output_stream_close_async();
+ * we called class->close_finish() from async_ready_close_callback_wrapper.
+ */
+ return g_task_propagate_boolean (G_TASK (result), error);
}
/**
@@ -1406,89 +1378,80 @@ typedef struct {
const void *buffer;
gsize count_requested;
gssize count_written;
-
- GCancellable *cancellable;
- gint io_priority;
- gboolean need_idle;
} WriteData;
static void
free_write_data (WriteData *op)
{
- if (op->cancellable)
- g_object_unref (op->cancellable);
g_slice_free (WriteData, op);
}
static void
-write_async_thread (GSimpleAsyncResult *res,
- GObject *object,
- GCancellable *cancellable)
+write_async_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
- WriteData *op;
+ GOutputStream *stream = source_object;
+ WriteData *op = task_data;
GOutputStreamClass *class;
GError *error = NULL;
+ gssize count_written;
- class = G_OUTPUT_STREAM_GET_CLASS (object);
- op = g_simple_async_result_get_op_res_gpointer (res);
- op->count_written = class->write_fn (G_OUTPUT_STREAM (object), op->buffer, op->count_requested,
- cancellable, &error);
- if (op->count_written == -1)
- g_simple_async_result_take_error (res, error);
+ class = G_OUTPUT_STREAM_GET_CLASS (stream);
+ count_written = class->write_fn (stream, op->buffer, op->count_requested,
+ cancellable, &error);
+ if (count_written == -1)
+ g_task_return_error (task, error);
+ else
+ g_task_return_int (task, count_written);
}
static void write_async_pollable (GPollableOutputStream *stream,
- GSimpleAsyncResult *result);
+ GTask *task);
static gboolean
write_async_pollable_ready (GPollableOutputStream *stream,
gpointer user_data)
{
- GSimpleAsyncResult *result = user_data;
+ GTask *task = user_data;
- write_async_pollable (stream, result);
+ write_async_pollable (stream, task);
return FALSE;
}
static void
write_async_pollable (GPollableOutputStream *stream,
- GSimpleAsyncResult *result)
+ GTask *task)
{
GError *error = NULL;
- WriteData *op = g_simple_async_result_get_op_res_gpointer (result);
+ WriteData *op = g_task_get_task_data (task);
+ gssize count_written;
- if (g_cancellable_set_error_if_cancelled (op->cancellable, &error))
- op->count_written = -1;
- else
- {
- op->count_written = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)->
- write_nonblocking (stream, op->buffer, op->count_requested, &error);
- }
+ if (g_task_return_error_if_cancelled (task))
+ return;
+
+ count_written = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)->
+ write_nonblocking (stream, op->buffer, op->count_requested, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
{
GSource *source;
g_error_free (error);
- op->need_idle = FALSE;
-
- source = g_pollable_output_stream_create_source (stream, op->cancellable);
- g_source_set_callback (source,
- (GSourceFunc) write_async_pollable_ready,
- g_object_ref (result), g_object_unref);
- g_source_set_priority (source, op->io_priority);
- g_source_attach (source, g_main_context_get_thread_default ());
+
+ source = g_pollable_output_stream_create_source (stream,
+ g_task_get_cancellable (task));
+ g_task_attach_source (task, source,
+ (GSourceFunc) write_async_pollable_ready);
g_source_unref (source);
return;
}
- if (op->count_written == -1)
- g_simple_async_result_take_error (result, error);
-
- if (op->need_idle)
- g_simple_async_result_complete_in_idle (result);
+ if (count_written == -1)
+ g_task_return_error (task, error);
else
- g_simple_async_result_complete (result);
+ g_task_return_int (task, count_written);
}
static void
@@ -1500,24 +1463,22 @@ g_output_stream_real_write_async (GOutputStream *stream,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *res;
+ GTask *task;
WriteData *op;
op = g_slice_new0 (WriteData);
- res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
- g_simple_async_result_set_op_res_gpointer (res, op, (GDestroyNotify) free_write_data);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_check_cancellable (task, FALSE);
+ g_task_set_task_data (task, op, (GDestroyNotify) free_write_data);
op->buffer = buffer;
op->count_requested = count;
- op->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- op->io_priority = io_priority;
- op->need_idle = TRUE;
-
+
if (G_IS_POLLABLE_OUTPUT_STREAM (stream) &&
g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (stream)))
- write_async_pollable (G_POLLABLE_OUTPUT_STREAM (stream), res);
+ write_async_pollable (G_POLLABLE_OUTPUT_STREAM (stream), task);
else
- g_simple_async_result_run_in_thread (res, write_async_thread, io_priority, cancellable);
- g_object_unref (res);
+ g_task_run_in_thread (task, write_async_thread);
+ g_object_unref (task);
}
static gssize
@@ -1525,45 +1486,46 @@ g_output_stream_real_write_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
- WriteData *op;
-
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_write_async);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return -1;
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
- op = g_simple_async_result_get_op_res_gpointer (simple);
- return op->count_written;
+ return g_task_propagate_int (G_TASK (result), error);
}
typedef struct {
GInputStream *source;
GOutputStreamSpliceFlags flags;
- gssize bytes_copied;
} SpliceData;
static void
-splice_async_thread (GSimpleAsyncResult *result,
- GObject *object,
- GCancellable *cancellable)
+free_splice_data (SpliceData *op)
{
- SpliceData *op;
+ g_object_unref (op->source);
+ g_slice_free (SpliceData, op);
+}
+
+static void
+splice_async_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ GOutputStream *stream = source_object;
+ SpliceData *op = task_data;
GOutputStreamClass *class;
GError *error = NULL;
- GOutputStream *stream;
+ gssize bytes_copied;
- stream = G_OUTPUT_STREAM (object);
- class = G_OUTPUT_STREAM_GET_CLASS (object);
- op = g_simple_async_result_get_op_res_gpointer (result);
+ class = G_OUTPUT_STREAM_GET_CLASS (stream);
- op->bytes_copied = class->splice (stream,
- op->source,
- op->flags,
- cancellable,
- &error);
- if (op->bytes_copied == -1)
- g_simple_async_result_take_error (result, error);
+ bytes_copied = class->splice (stream,
+ op->source,
+ op->flags,
+ cancellable,
+ &error);
+ if (bytes_copied == -1)
+ g_task_return_error (task, error);
+ else
+ g_task_return_int (task, bytes_copied);
}
static void
@@ -1575,20 +1537,20 @@ g_output_stream_real_splice_async (GOutputStream *stream,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *res;
+ GTask *task;
SpliceData *op;
- op = g_new0 (SpliceData, 1);
- res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_splice_async);
- g_simple_async_result_set_op_res_gpointer (res, op, g_free);
+ op = g_slice_new0 (SpliceData);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_task_data (task, op, (GDestroyNotify)free_splice_data);
op->flags = flags;
- op->source = source;
+ op->source = g_object_ref (source);
/* TODO: In the case where both source and destintion have
non-threadbased async calls we can use a true async copy here */
- g_simple_async_result_run_in_thread (res, splice_async_thread, io_priority, cancellable);
- g_object_unref (res);
+ g_task_run_in_thread (task, splice_async_thread);
+ g_object_unref (task);
}
static gssize
@@ -1596,35 +1558,32 @@ g_output_stream_real_splice_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
- SpliceData *op;
-
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_splice_async);
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
- if (g_simple_async_result_propagate_error (simple, error))
- return -1;
-
- op = g_simple_async_result_get_op_res_gpointer (simple);
- return op->bytes_copied;
+ return g_task_propagate_int (G_TASK (result), error);
}
static void
-flush_async_thread (GSimpleAsyncResult *res,
- GObject *object,
- GCancellable *cancellable)
+flush_async_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
+ GOutputStream *stream = source_object;
GOutputStreamClass *class;
gboolean result;
GError *error = NULL;
- class = G_OUTPUT_STREAM_GET_CLASS (object);
+ class = G_OUTPUT_STREAM_GET_CLASS (stream);
result = TRUE;
if (class->flush)
- result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error);
+ result = class->flush (stream, cancellable, &error);
- if (!result)
- g_simple_async_result_take_error (res, error);
+ if (result)
+ g_task_return_boolean (task, TRUE);
+ else
+ g_task_return_error (task, error);
}
static void
@@ -1634,12 +1593,12 @@ g_output_stream_real_flush_async (GOutputStream *stream,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *res;
+ GTask *task;
- res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
-
- g_simple_async_result_run_in_thread (res, flush_async_thread, io_priority, cancellable);
- g_object_unref (res);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_priority (task, io_priority);
+ g_task_run_in_thread (task, flush_async_thread);
+ g_object_unref (task);
}
static gboolean
@@ -1647,49 +1606,52 @@ g_output_stream_real_flush_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
- return TRUE;
+ return g_task_propagate_boolean (G_TASK (result), error);
}
static void
-close_async_thread (GSimpleAsyncResult *res,
- GObject *object,
- GCancellable *cancellable)
+close_async_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
+ GOutputStream *stream = source_object;
GOutputStreamClass *class;
GError *error = NULL;
gboolean result = TRUE;
- class = G_OUTPUT_STREAM_GET_CLASS (object);
+ class = G_OUTPUT_STREAM_GET_CLASS (stream);
/* Do a flush here if there is a flush function, and we did not have to do
- an async flush before (see g_output_stream_close_async) */
+ * an async flush before (see g_output_stream_close_async)
+ */
if (class->flush != NULL &&
(class->flush_async == NULL ||
class->flush_async == g_output_stream_real_flush_async))
{
- result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error);
+ result = class->flush (stream, cancellable, &error);
}
/* Auto handling of cancelation disabled, and ignore
cancellation, since we want to close things anyway, although
possibly in a quick-n-dirty way. At least we never want to leak
open handles */
-
+
if (class->close_fn)
{
/* Make sure to close, even if the flush failed (see sync close) */
if (!result)
- class->close_fn (G_OUTPUT_STREAM (object), cancellable, NULL);
+ class->close_fn (stream, cancellable, NULL);
else
- result = class->close_fn (G_OUTPUT_STREAM (object), cancellable, &error);
-
- if (!result)
- g_simple_async_result_take_error (res, error);
+ result = class->close_fn (stream, cancellable, &error);
}
+
+ if (result)
+ g_task_return_boolean (task, TRUE);
+ else
+ g_task_return_error (task, error);
}
static void
@@ -1699,14 +1661,12 @@ g_output_stream_real_close_async (GOutputStream *stream,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *res;
-
- res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_close_async);
+ GTask *task;
- g_simple_async_result_set_handle_cancellation (res, FALSE);
-
- g_simple_async_result_run_in_thread (res, close_async_thread, io_priority, cancellable);
- g_object_unref (res);
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_priority (task, io_priority);
+ g_task_run_in_thread (task, close_async_thread);
+ g_object_unref (task);
}
static gboolean
@@ -1714,11 +1674,7 @@ g_output_stream_real_close_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_close_async);
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
- return TRUE;
+ return g_task_propagate_boolean (G_TASK (result), error);
}
diff --git a/gio/gunixinputstream.c b/gio/gunixinputstream.c
index a1639f6..f65eb18 100644
--- a/gio/gunixinputstream.c
+++ b/gio/gunixinputstream.c
@@ -425,20 +425,16 @@ g_unix_input_stream_close (GInputStream *stream,
if (!unix_stream->priv->close_fd)
return TRUE;
- while (1)
+ /* This might block during the close. Doesn't seem to be a way to avoid it though. */
+ res = close (unix_stream->priv->fd);
+ if (res == -1)
{
- /* This might block during the close. Doesn't seem to be a way to avoid it though. */
- res = close (unix_stream->priv->fd);
- if (res == -1)
- {
- int errsv = errno;
+ int errsv = errno;
- g_set_error (error, G_IO_ERROR,
- g_io_error_from_errno (errsv),
- _("Error closing file descriptor: %s"),
- g_strerror (errsv));
- }
- break;
+ g_set_error (error, G_IO_ERROR,
+ g_io_error_from_errno (errsv),
+ _("Error closing file descriptor: %s"),
+ g_strerror (errsv));
}
return res != -1;
@@ -467,67 +463,27 @@ g_unix_input_stream_skip_finish (GInputStream *stream,
}
-typedef struct {
- GInputStream *stream;
- GAsyncReadyCallback callback;
- gpointer user_data;
-} CloseAsyncData;
-
-static void
-close_async_data_free (gpointer _data)
-{
- CloseAsyncData *data = _data;
-
- g_free (data);
-}
-
static gboolean
-close_async_cb (CloseAsyncData *data)
+close_async_cb (gpointer user_data)
{
- GUnixInputStream *unix_stream;
- GSimpleAsyncResult *simple;
- GError *error = NULL;
- gboolean result;
+ GTask *task = user_data;
+ GUnixInputStream *unix_stream = g_task_get_source_object (task);
int res;
- unix_stream = G_UNIX_INPUT_STREAM (data->stream);
-
- if (!unix_stream->priv->close_fd)
- {
- result = TRUE;
- goto out;
- }
-
- while (1)
+ res = close (unix_stream->priv->fd);
+ if (res == -1)
{
- res = close (unix_stream->priv->fd);
- if (res == -1)
- {
- int errsv = errno;
+ int errsv = errno;
- g_set_error (&error, G_IO_ERROR,
- g_io_error_from_errno (errsv),
- _("Error closing file descriptor: %s"),
- g_strerror (errsv));
- }
- break;
+ g_task_return_new_error (task, G_IO_ERROR,
+ g_io_error_from_errno (errsv),
+ _("Error closing file descriptor: %s"),
+ g_strerror (errsv));
}
-
- result = res != -1;
-
- out:
- simple = g_simple_async_result_new (G_OBJECT (data->stream),
- data->callback,
- data->user_data,
- g_unix_input_stream_close_async);
-
- if (!result)
- g_simple_async_result_take_error (simple, error);
+ else
+ g_task_return_boolean (task, TRUE);
- /* Complete immediately, not in idle, since we're already in a mainloop callout */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-
+ g_object_unref (task);
return FALSE;
}
@@ -538,18 +494,21 @@ g_unix_input_stream_close_async (GInputStream *stream,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ GUnixInputStream *unix_stream = G_UNIX_INPUT_STREAM (stream);
+ GTask *task;
GSource *idle;
- CloseAsyncData *data;
- data = g_new0 (CloseAsyncData, 1);
-
- data->stream = stream;
- data->callback = callback;
- data->user_data = user_data;
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_priority (task, io_priority);
+ if (!unix_stream->priv->close_fd)
+ {
+ g_task_return_boolean (task, TRUE);
+ return;
+ }
+
idle = g_idle_source_new ();
- g_source_set_callback (idle, (GSourceFunc)close_async_cb, data, close_async_data_free);
- g_source_attach (idle, g_main_context_get_thread_default ());
+ g_task_attach_source (task, idle, close_async_cb);
g_source_unref (idle);
}
@@ -558,8 +517,9 @@ g_unix_input_stream_close_finish (GInputStream *stream,
GAsyncResult *result,
GError **error)
{
- /* Failures handled in generic close_finish code */
- return TRUE;
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
}
static gboolean
diff --git a/gio/gunixoutputstream.c b/gio/gunixoutputstream.c
index 4e00dcb..1084132 100644
--- a/gio/gunixoutputstream.c
+++ b/gio/gunixoutputstream.c
@@ -411,100 +411,67 @@ g_unix_output_stream_close (GOutputStream *stream,
if (!unix_stream->priv->close_fd)
return TRUE;
- while (1)
+ /* This might block during the close. Doesn't seem to be a way to avoid it though. */
+ res = close (unix_stream->priv->fd);
+ if (res == -1)
{
- /* This might block during the close. Doesn't seem to be a way to avoid it though. */
- res = close (unix_stream->priv->fd);
- if (res == -1)
- {
- int errsv = errno;
+ int errsv = errno;
- g_set_error (error, G_IO_ERROR,
- g_io_error_from_errno (errsv),
- _("Error closing file descriptor: %s"),
- g_strerror (errsv));
- }
- break;
+ g_set_error (error, G_IO_ERROR,
+ g_io_error_from_errno (errsv),
+ _("Error closing file descriptor: %s"),
+ g_strerror (errsv));
}
return res != -1;
}
-typedef struct {
- GOutputStream *stream;
- GAsyncReadyCallback callback;
- gpointer user_data;
-} CloseAsyncData;
-
static gboolean
-close_async_cb (CloseAsyncData *data)
+close_async_cb (gpointer user_data)
{
- GUnixOutputStream *unix_stream;
- GSimpleAsyncResult *simple;
- GError *error = NULL;
- gboolean result;
+ GTask *task = user_data;
+ GUnixOutputStream *unix_stream = g_task_get_source_object (task);
int res;
- unix_stream = G_UNIX_OUTPUT_STREAM (data->stream);
-
- if (!unix_stream->priv->close_fd)
+ res = close (unix_stream->priv->fd);
+ if (res == -1)
{
- result = TRUE;
- goto out;
- }
-
- while (1)
- {
- res = close (unix_stream->priv->fd);
- if (res == -1)
- {
- int errsv = errno;
+ int errsv = errno;
- g_set_error (&error, G_IO_ERROR,
- g_io_error_from_errno (errsv),
- _("Error closing file descriptor: %s"),
- g_strerror (errsv));
- }
- break;
+ g_task_return_new_error (task, G_IO_ERROR,
+ g_io_error_from_errno (errsv),
+ _("Error closing file descriptor: %s"),
+ g_strerror (errsv));
}
-
- result = res != -1;
-
- out:
- simple = g_simple_async_result_new (G_OBJECT (data->stream),
- data->callback,
- data->user_data,
- g_unix_output_stream_close_async);
-
- if (!result)
- g_simple_async_result_take_error (simple, error);
-
- /* Complete immediately, not in idle, since we're already in a mainloop callout */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-
+ else
+ g_task_return_boolean (task, TRUE);
+
+ g_object_unref (task);
return FALSE;
}
static void
-g_unix_output_stream_close_async (GOutputStream *stream,
+g_unix_output_stream_close_async (GOutputStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ GUnixOutputStream *unix_stream = G_UNIX_OUTPUT_STREAM (stream);
+ GTask *task;
GSource *idle;
- CloseAsyncData *data;
- data = g_new0 (CloseAsyncData, 1);
-
- data->stream = stream;
- data->callback = callback;
- data->user_data = user_data;
+ task = g_task_new (stream, cancellable, callback, user_data);
+ g_task_set_priority (task, io_priority);
+ if (!unix_stream->priv->close_fd)
+ {
+ g_task_return_boolean (task, TRUE);
+ return;
+ }
+
idle = g_idle_source_new ();
- g_source_set_callback (idle, (GSourceFunc)close_async_cb, data, g_free);
- g_source_attach (idle, g_main_context_get_thread_default ());
+ g_task_attach_source (task, idle, close_async_cb);
g_source_unref (idle);
}
@@ -513,8 +480,9 @@ g_unix_output_stream_close_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
- /* Failures handled in generic close_finish code */
- return TRUE;
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
}
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]