gio: port basic I/O classes from GSimpleAsyncResult to GTask

https://bugzilla.gnome.org/show_bug.cgi?id=661767
This commit is contained in:
Dan Winship
2012-08-02 15:49:59 -04:00
parent 3c87ab97ff
commit a3256696b0
10 changed files with 770 additions and 1149 deletions

View File

@@ -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,36 @@ g_buffered_input_stream_fill_async (GBufferedInputStream *stream,
gpointer user_data)
{
GBufferedInputStreamClass *class;
GSimpleAsyncResult *simple;
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);
GTask *task;
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);
g_task_report_new_error (stream, callback, user_data,
g_buffered_input_stream_fill_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 (G_INPUT_STREAM (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_buffered_input_stream_fill_async,
error);
return;
}
@@ -550,10 +547,7 @@ g_buffered_input_stream_fill_finish (GBufferedInputStream *stream,
if (g_async_result_legacy_propagate_error (result, error))
return -1;
else if (g_async_result_is_tagged (result, g_buffered_input_stream_fill_async))
{
/* Special case read of 0 bytes */
return 0;
}
return g_task_propagate_int (G_TASK (result), error);
class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
return class->fill_finish (stream, result, error);
@@ -1041,38 +1035,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 +1069,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 +1086,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 +1095,7 @@ g_buffered_input_stream_real_fill_async (GBufferedInputStream *stream,
io_priority,
cancellable,
fill_async_callback,
simple);
task);
}
static gssize
@@ -1121,17 +1103,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 +1126,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 +1139,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 +1159,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 +1170,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);
data->bytes_skipped += data->count;
priv->pos += data->count;
if (nread > 0)
{
available = priv->end - priv->pos;
data->count = MIN (data->count, available);
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 +1211,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 +1219,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 +1255,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 +1270,7 @@ g_buffered_input_stream_skip_finish (GInputStream *stream,
GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *simple;
SkipAsyncData *data;
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_skip_async);
data = g_simple_async_result_get_op_res_gpointer (simple);
return data->bytes_skipped;
return g_task_propagate_int (G_TASK (result), error);
}