Creating a serialized JSON object is a time consuming process.

Add a json_serialized_object_create_with_yield() function that
makes use of the cooperative multitasking module to yield during
processing, allowing time sensitive tasks in other parts of the
program to be completed during processing.

Signed-off-by: Frode Nordahl <frode.nord...@canonical.com>
---
 include/openvswitch/json.h |  4 +++-
 lib/json.c                 | 43 +++++++++++++++++++++++++++-----------
 2 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/include/openvswitch/json.h b/include/openvswitch/json.h
index 35b403c29..252425393 100644
--- a/include/openvswitch/json.h
+++ b/include/openvswitch/json.h
@@ -81,6 +81,7 @@ struct json *json_boolean_create(bool);
 struct json *json_string_create(const char *);
 struct json *json_string_create_nocopy(char *);
 struct json *json_serialized_object_create(const struct json *);
+struct json *json_serialized_object_create_with_yield(const struct json *);
 struct json *json_integer_create(long long int);
 struct json *json_real_create(double);
 
@@ -137,7 +138,8 @@ struct json *json_from_stream(FILE *stream);
 
 enum {
     JSSF_PRETTY = 1 << 0,       /* Multiple lines with indentation, if true. */
-    JSSF_SORT = 1 << 1          /* Object members in sorted order, if true. */
+    JSSF_SORT = 1 << 1,         /* Object members in sorted order, if true. */
+    JSSF_YIELD = 1 << 2         /* Yield during processing */
 };
 char *json_to_string(const struct json *, int flags);
 void json_to_ds(const struct json *, int flags, struct ds *);
diff --git a/lib/json.c b/lib/json.c
index aded8bb01..9a264777a 100644
--- a/lib/json.c
+++ b/lib/json.c
@@ -24,6 +24,7 @@
 #include <limits.h>
 #include <string.h>
 
+#include "cooperative-multitasking.h"
 #include "openvswitch/dynamic-string.h"
 #include "hash.h"
 #include "openvswitch/shash.h"
@@ -181,14 +182,26 @@ json_string_create(const char *s)
     return json_string_create_nocopy(xstrdup(s));
 }
 
-struct json *
-json_serialized_object_create(const struct json *src)
+static struct json *
+json_serialized_object_create__(const struct json *src, int flags)
 {
     struct json *json = json_create(JSON_SERIALIZED_OBJECT);
-    json->string = json_to_string(src, JSSF_SORT);
+    json->string = json_to_string(src, flags);
     return json;
 }
 
+struct json *
+json_serialized_object_create(const struct json *src)
+{
+    return json_serialized_object_create__(src, JSSF_SORT);
+}
+
+struct json *
+json_serialized_object_create_with_yield(const struct json *src)
+{
+    return json_serialized_object_create__(src, JSSF_SORT | JSSF_YIELD);
+}
+
 struct json *
 json_array_create_empty(void)
 {
@@ -1525,7 +1538,7 @@ static void json_serialize_object(const struct shash 
*object,
                                   struct json_serializer *);
 static void json_serialize_array(const struct json_array *,
                                  struct json_serializer *);
-static void json_serialize_string(const char *, struct ds *);
+static void json_serialize_string(const char *, struct json_serializer *);
 
 /* Converts 'json' to a string in JSON format, encoded in UTF-8, and returns
  * that string.  The caller is responsible for freeing the returned string,
@@ -1598,7 +1611,7 @@ json_serialize(const struct json *json, struct 
json_serializer *s)
         break;
 
     case JSON_STRING:
-        json_serialize_string(json->string, ds);
+        json_serialize_string(json->string, s);
         break;
 
     case JSON_SERIALIZED_OBJECT:
@@ -1631,7 +1644,7 @@ json_serialize_object_member(size_t i, const struct 
shash_node *node,
         indent_line(s);
     }
 
-    json_serialize_string(node->name, ds);
+    json_serialize_string(node->name, s);
     ds_put_char(ds, ':');
     if (s->flags & JSSF_PRETTY) {
         ds_put_char(ds, ' ');
@@ -1734,7 +1747,7 @@ static const char *chars_escaping[256] = {
 };
 
 static void
-json_serialize_string(const char *string, struct ds *ds)
+json_serialize_string(const char *string, struct json_serializer *s)
 {
     uint8_t c;
     uint8_t c2;
@@ -1742,26 +1755,32 @@ json_serialize_string(const char *string, struct ds *ds)
     const char *escape;
     const char *start;
 
-    ds_put_char(ds, '"');
+    ds_put_char(s->ds, '"');
     count = 0;
     start = string;
     while ((c = *string++) != '\0') {
+        if (s->flags & JSSF_YIELD) {
+            cooperative_multitasking_yield();
+        }
         if (c >= ' ' && c != '"' && c != '\\') {
             count++;
         } else {
             if (count) {
-                ds_put_buffer(ds, start, count);
+                ds_put_buffer(s->ds, start, count);
                 count = 0;
             }
             start = string;
             escape = chars_escaping[c];
             while ((c2 = *escape++) != '\0') {
-                ds_put_char(ds, c2);
+                if (s->flags & JSSF_YIELD) {
+                    cooperative_multitasking_yield();
+                }
+                ds_put_char(s->ds, c2);
             }
         }
     }
     if (count) {
-        ds_put_buffer(ds, start, count);
+        ds_put_buffer(s->ds, start, count);
     }
-    ds_put_char(ds, '"');
+    ds_put_char(s->ds, '"');
 }
-- 
2.34.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to