summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammed Sadiq <sadiq@sadiqpk.org>2022-09-16 19:23:18 +0530
committerMohammed Sadiq <sadiq@sadiqpk.org>2022-09-16 19:23:18 +0530
commitcfbbdfbafc39c69a54ab830faa89a2b4c26e7561 (patch)
treee637b7f6ee10d0819e5b5c86bd139b05dafc3ad9
parentac12297654adf8195b49d20e4c662a01f2b96e5a (diff)
downloadjson-glib-wip/sadiq/parser-read-async.tar.gz
parser: Don't use thread to read async from streamwip/sadiq/parser-read-async
Some GInputStream may not support reading from a different thread (eg: libsoup3[0]). So instead of reading the stream in the task thread, use the async read API of GInputStream. Since read_async is optional (as GLib handles it if not implemented) This shouldn't be an issue for users. [0] https://libsoup.org/libsoup-3.0/client-thread-safety.html
-rw-r--r--json-glib/json-parser.c53
1 files changed, 32 insertions, 21 deletions
diff --git a/json-glib/json-parser.c b/json-glib/json-parser.c
index c5e58f4..773d106 100644
--- a/json-glib/json-parser.c
+++ b/json-glib/json-parser.c
@@ -1557,35 +1557,41 @@ json_parser_load_from_stream_finish (JsonParser *parser,
}
static void
-read_from_stream (GTask *task,
- gpointer source_obj,
- gpointer task_data,
- GCancellable *cancellable)
+read_from_stream (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- LoadData *data = task_data;
+ GTask *task = user_data;
GError *error = NULL;
+ LoadData *data;
gssize res;
- data->pos = 0;
- g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE + 1);
- while ((res = g_input_stream_read (data->stream,
- data->content->data + data->pos,
- GET_DATA_BLOCK_SIZE,
- cancellable, &error)) > 0)
+ data = g_task_get_task_data (task);
+ res = g_input_stream_read_finish (G_INPUT_STREAM (object), result, &error);
+
+ if (res < 0)
+ {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ }
+ else if (res > 0)
{
data->pos += res;
g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE + 1);
+ g_input_stream_read_async (data->stream,
+ data->content->data + data->pos,
+ GET_DATA_BLOCK_SIZE,
+ G_PRIORITY_DEFAULT,
+ g_task_get_cancellable (task),
+ read_from_stream, task);
}
-
- if (res < 0)
+ else
{
- g_task_return_error (task, error);
- return;
+ /* zero-terminate the content; we allocated an extra byte for this */
+ data->content->data[data->pos] = 0;
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
-
- /* zero-terminate the content; we allocated an extra byte for this */
- data->content->data[data->pos] = 0;
- g_task_return_boolean (task, TRUE);
}
/**
@@ -1629,6 +1635,11 @@ json_parser_load_from_stream_async (JsonParser *parser,
task = g_task_new (parser, cancellable, callback, user_data);
g_task_set_task_data (task, data, load_data_free);
- g_task_run_in_thread (task, read_from_stream);
- g_object_unref (task);
+ g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE + 1);
+ g_input_stream_read_async (data->stream,
+ data->content->data + data->pos,
+ GET_DATA_BLOCK_SIZE,
+ G_PRIORITY_DEFAULT,
+ cancellable,
+ read_from_stream, task);
}