diff options
author | Thomas Haller <thaller@redhat.com> | 2023-03-30 18:49:00 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-04-04 08:43:21 +0200 |
commit | 64825b4f58489f64c6cde82c76c373264985b448 (patch) | |
tree | e59181bb232aaa791041941be419d665978ec048 | |
parent | 1378ed7d963bf10cdeb28b7999ad490ca8963509 (diff) | |
download | NetworkManager-64825b4f58489f64c6cde82c76c373264985b448.tar.gz |
ovsdb: don't track buffer offset in NMOvsdb data and refactor parsing JSON messages
The "priv->bufp" offset is only used while parsing a message at a time.
It's unnecessary to track it in NMOvsdbPrivate and keep it between
parsing messages. Tracking the state in NMOvsdbPrivate makes it more
complicated to understand, because one needs to reason at which times
the state is used (when it really is not used).
Also, move the parsing to a separate function.
-rw-r--r-- | src/core/devices/ovs/nm-ovsdb.c | 71 |
1 files changed, 46 insertions, 25 deletions
diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c index 85b7953f7e..50239be6c7 100644 --- a/src/core/devices/ovs/nm-ovsdb.c +++ b/src/core/devices/ovs/nm-ovsdb.c @@ -138,7 +138,6 @@ typedef struct { GSocketConnection *conn; GCancellable *conn_cancellable; char buf[4096]; /* Input buffer */ - size_t bufp; /* Last decoded byte in the input buffer. */ GString *input; /* JSON stream waiting for decoding. */ GString *output; /* JSON stream to be sent. */ guint64 call_id_counter; @@ -2320,25 +2319,55 @@ ovsdb_got_msg(NMOvsdb *self, json_t *msg) /*****************************************************************************/ +typedef struct { + gsize bufp; + GString *input; +} JsonReadMsgData; + /* Lower level marshalling and demarshalling of the JSON-RPC traffic on the * ovsdb socket. */ static size_t -_json_callback(void *buffer, size_t buflen, void *user_data) +_json_read_msg_cb(void *buffer, size_t buflen, void *user_data) { - NMOvsdb *self = NM_OVSDB(user_data); - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); + JsonReadMsgData *data = user_data; - if (priv->bufp == priv->input->len) { + nm_assert(buffer); + nm_assert(buflen > 0); + + if (data->bufp == data->input->len) { /* No more bytes buffered for decoding. */ return 0; } /* Pass one more byte to the JSON decoder. */ - *(char *) buffer = priv->input->str[priv->bufp]; - priv->bufp++; + *(char *) buffer = data->input->str[data->bufp]; + data->bufp++; + return 1; +} + +static json_t * +_json_read_msg(GString *input) +{ + JsonReadMsgData data = { + .bufp = 0, + .input = input, + }; + json_error_t json_error = { + 0, + }; + json_t *msg; - return (size_t) 1; + /* The callback always eats up only up to a single byte. This makes it + * possible for us to identify complete JSON objects in spite of us not + * knowing the length in advance. */ + msg = json_load_callback(_json_read_msg_cb, &data, JSON_DISABLE_EOF_CHECK, &json_error); + if (!msg) + return NULL; + + nm_assert(data.bufp > 0); + g_string_erase(input, 0, data.bufp); + return msg; } /** @@ -2355,10 +2384,6 @@ ovsdb_read_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) GInputStream *stream = G_INPUT_STREAM(source_object); GError *error = NULL; gssize size; - json_t *msg; - json_error_t json_error = { - 0, - }; size = g_input_stream_read_finish(stream, res, &error); if (size == -1) { @@ -2371,18 +2396,15 @@ ovsdb_read_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) } g_string_append_len(priv->input, priv->buf, size); - do { - priv->bufp = 0; - /* The callback always eats up only up to a single byte. This makes - * it possible for us to identify complete JSON objects in spite of - * us not knowing the length in advance. */ - msg = json_load_callback(_json_callback, self, JSON_DISABLE_EOF_CHECK, &json_error); - if (msg) { - ovsdb_got_msg(self, msg); - g_string_erase(priv->input, 0, priv->bufp); - } - json_decref(msg); - } while (msg); + while (TRUE) { + nm_auto_decref_json json_t *msg = NULL; + + msg = _json_read_msg(priv->input); + if (!msg) + break; + + ovsdb_got_msg(self, msg); + } if (!priv->conn) return; @@ -2498,7 +2520,6 @@ ovsdb_disconnect(NMOvsdb *self, gboolean retry, gboolean is_disposing) _call_complete(call, NULL, error); } - priv->bufp = 0; g_string_truncate(priv->input, 0); g_string_truncate(priv->output, 0); g_clear_object(&priv->conn); |