[json-glib/wip/sadiq/parser-read-async] parser: Don't use thread to read async from stream




commit cfbbdfbafc39c69a54ab830faa89a2b4c26e7561
Author: Mohammed Sadiq <sadiq sadiqpk org>
Date:   Fri Sep 16 19:23:18 2022 +0530

    parser: Don't use thread to read async from stream
    
    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

 json-glib/json-parser.c | 53 +++++++++++++++++++++++++++++--------------------
 1 file 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);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]