diff options
author | Mohammed Sadiq <sadiq@sadiqpk.org> | 2022-09-16 19:23:18 +0530 |
---|---|---|
committer | Mohammed Sadiq <sadiq@sadiqpk.org> | 2022-09-16 19:23:18 +0530 |
commit | cfbbdfbafc39c69a54ab830faa89a2b4c26e7561 (patch) | |
tree | e637b7f6ee10d0819e5b5c86bd139b05dafc3ad9 | |
parent | ac12297654adf8195b49d20e4c662a01f2b96e5a (diff) | |
download | json-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.c | 53 |
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); } |