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