All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Marc-André Lureau" <marcandre.lureau@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Eduardo Habkost" <ehabkost@redhat.com>,
	"Juan Quintela" <quintela@redhat.com>,
	"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
	"Eric Blake" <eblake@redhat.com>,
	"Cleber Rosa" <crosa@redhat.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Gerd Hoffmann" <kraxel@redhat.com>,
	"Michael Roth" <mdroth@linux.vnet.ibm.com>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>
Subject: [Qemu-devel] [PATCH v3 20/38] QmpSession: add json parser and use it in qga
Date: Mon, 26 Mar 2018 17:08:58 +0200	[thread overview]
Message-ID: <20180326150916.9602-21-marcandre.lureau@redhat.com> (raw)
In-Reply-To: <20180326150916.9602-1-marcandre.lureau@redhat.com>

Move JSON parser to QmpSession, and implement a simple handler to check
the parsed tokens and call qmp_dispatch(). This is enough for a simple
QMP client, like QGA.

The QEMU monitor has more complicated handling of dispatching which
will be adressed in following patch to benefit more common code.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qapi/qmp/dispatch.h |  9 ++++++++
 monitor.c                   |  7 ++-----
 qapi/qmp-dispatch.c         | 32 +++++++++++++++++++++++++++++
 qga/main.c                  | 41 +------------------------------------
 4 files changed, 44 insertions(+), 45 deletions(-)

diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index 7bf0b6a437..cd425b8574 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -15,6 +15,7 @@
 #define QAPI_QMP_DISPATCH_H
 
 #include "qemu/queue.h"
+#include "qapi/qmp/json-streamer.h"
 
 typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
 
@@ -40,6 +41,7 @@ typedef struct QmpSession QmpSession;
 typedef void (QmpDispatchReturn) (QmpSession *session, QDict *rsp);
 
 struct QmpSession {
+    JSONMessageParser parser;
     QmpDispatchReturn *return_cb;
     QmpCommandList *cmds;
 };
@@ -48,9 +50,16 @@ void qmp_register_command(QmpCommandList *cmds, const char *name,
                           QmpCommandFunc *fn, QmpCommandOptions options);
 void qmp_unregister_command(QmpCommandList *cmds, const char *name);
 QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name);
+
 void qmp_session_init(QmpSession *session,
                       QmpCommandList *cmds, QmpDispatchReturn *return_cb);
 
+static inline void
+qmp_session_feed(QmpSession *session, const char *buf, size_t count)
+{
+    json_message_parser_feed(&session->parser, buf, count);
+}
+
 void qmp_session_destroy(QmpSession *session);
 void qmp_dispatch(QmpSession *session, QDict *request);
 void qmp_disable_command(QmpCommandList *cmds, const char *name);
diff --git a/monitor.c b/monitor.c
index 93ecb03d04..66046d4854 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3934,11 +3934,8 @@ static void dispatch_return_cb(QmpSession *session, QDict *rsp)
  */
 static void monitor_qmp_dispatch_one(QMPRequest *req_obj)
 {
-    Monitor *mon, *old_mon;
-    QDict *req;
-
-    req = req_obj->req;
-    mon = req_obj->mon;
+    Monitor *old_mon, *mon = req_obj->mon;
+    QDict *req = req_obj->req;
 
     g_free(req_obj);
 
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 5274aa59cc..5352b25e90 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -146,12 +146,43 @@ bool qmp_is_oob(const QDict *dict)
     return qbool_get_bool(bool_obj);
 }
 
+static void qmp_json_parser_emit(JSONMessageParser *parser, GQueue *tokens)
+{
+    QmpSession *session = container_of(parser, QmpSession, parser);
+    QObject *obj;
+    QDict *req;
+    Error *err = NULL;
+
+    obj = json_parser_parse_err(tokens, NULL, &err);
+    if (err) {
+        goto end;
+    }
+
+    req = qmp_dispatch_check_obj(obj, &err);
+    if (err) {
+        goto end;
+    }
+
+    qmp_dispatch(session, req);
+
+end:
+    if (err) {
+        QDict *rsp = qdict_new();
+        qdict_put_obj(rsp, "error", qmp_build_error_object(err));
+        error_free(err);
+        session->return_cb(session, rsp);
+        QDECREF(rsp);
+    }
+    qobject_decref(obj);
+}
+
 void qmp_session_init(QmpSession *session,
                       QmpCommandList *cmds, QmpDispatchReturn *return_cb)
 {
     assert(return_cb);
     assert(!session->return_cb);
 
+    json_message_parser_init(&session->parser, qmp_json_parser_emit);
     session->cmds = cmds;
     session->return_cb = return_cb;
 }
@@ -164,6 +195,7 @@ void qmp_session_destroy(QmpSession *session)
 
     session->cmds = NULL;
     session->return_cb = NULL;
+    json_message_parser_destroy(&session->parser);
 }
 
 void qmp_dispatch(QmpSession *session, QDict *req)
diff --git a/qga/main.c b/qga/main.c
index 46349395ba..ce7efff3b4 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -72,7 +72,6 @@ typedef struct GAPersistentState {
 
 struct GAState {
     QmpSession session;
-    JSONMessageParser parser;
     GMainLoop *main_loop;
     GAChannel *channel;
     bool virtio; /* fastpath to check for virtio to deal with poll() quirks */
@@ -589,42 +588,6 @@ static void dispatch_return_cb(QmpSession *session, QDict *rsp)
     }
 }
 
-/* handle requests/control events coming in over the channel */
-static void process_event(JSONMessageParser *parser, GQueue *tokens)
-{
-    GAState *s = container_of(parser, GAState, parser);
-    QObject *obj;
-    QDict *req;
-    Error *err = NULL;
-
-    g_assert(s && parser);
-
-    g_debug("process_event: called");
-
-    obj = json_parser_parse_err(tokens, NULL, &err);
-    if (err) {
-        goto end;
-    }
-
-    req = qmp_dispatch_check_obj(obj, &err);
-    if (err) {
-        goto end;
-    }
-
-    g_debug("processing command");
-    qmp_dispatch(&s->session, req);
-
-end:
-    if (err) {
-        QDict *rsp = qdict_new();
-        qdict_put_obj(rsp, "error", qmp_build_error_object(err));
-        error_free(err);
-        dispatch_return_cb(&s->session, rsp);
-        QDECREF(rsp);
-    }
-    qobject_decref(obj);
-}
-
 /* false return signals GAChannel to close the current client connection */
 static gboolean channel_event_cb(GIOCondition condition, gpointer data)
 {
@@ -639,7 +602,7 @@ static gboolean channel_event_cb(GIOCondition condition, gpointer data)
     case G_IO_STATUS_NORMAL:
         buf[count] = 0;
         g_debug("read data, count: %d, data: %s", (int)count, buf);
-        json_message_parser_feed(&s->parser, (char *)buf, (int)count);
+        qmp_session_feed(&s->session, buf, count);
         break;
     case G_IO_STATUS_EOF:
         g_debug("received EOF");
@@ -1307,7 +1270,6 @@ static int run_agent(GAState *s, GAConfig *config, int socket_activation)
     s->command_state = ga_command_state_new();
     ga_command_state_init(s, s->command_state);
     ga_command_state_init_all(s->command_state);
-    json_message_parser_init(&s->parser, process_event);
     qmp_session_init(&s->session, &ga_commands, dispatch_return_cb);
 #ifndef _WIN32
     if (!register_signal_handlers()) {
@@ -1431,7 +1393,6 @@ end:
         qmp_session_destroy(&s->session);
         ga_command_state_cleanup_all(s->command_state);
         ga_command_state_free(s->command_state);
-        json_message_parser_destroy(&s->parser);
     }
     if (s->channel) {
         ga_channel_free(s->channel);
-- 
2.17.0.rc1.1.g4c4f2b46a3

  parent reply	other threads:[~2018-03-26 15:10 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-26 15:08 [Qemu-devel] [PATCH v3 00/38] RFC: monitor: add asynchronous command type Marc-André Lureau
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 01/38] HACK: add back OOB Marc-André Lureau
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 02/38] qmp-shell: learn to send commands with quoted arguments Marc-André Lureau
2018-03-26 18:26   ` Eduardo Habkost
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 03/38] Revert "qmp: isolate responses into io thread" Marc-André Lureau
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 04/38] monitor: no need to save need_resume Marc-André Lureau
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 05/38] monitor: further simplify previous patch Marc-André Lureau
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 06/38] monitor: no need to remove desc before replacing it Marc-André Lureau
2018-03-26 19:31   ` Eric Blake
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 07/38] json-parser: always set an error if return NULL Marc-André Lureau
2018-07-05 11:35   ` Markus Armbruster
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 08/38] json-lexer: make it safe to call multiple times Marc-André Lureau
2018-07-05 11:42   ` Markus Armbruster
2018-07-05 12:17     ` Marc-André Lureau
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 09/38] json: remove useless return value from lexer/parser Marc-André Lureau
2018-07-05 11:49   ` Markus Armbruster
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 10/38] tests: add a few qemu-qmp tests Marc-André Lureau
2018-07-05 11:55   ` Markus Armbruster
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 11/38] tests: change /0.15/* tests to /qmp/* Marc-André Lureau
2018-07-05 11:56   ` Markus Armbruster
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 12/38] tests: add a qmp success-response test Marc-André Lureau
2018-07-05 11:59   ` Markus Armbruster
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 13/38] qga: process_event() simplification Marc-André Lureau
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 14/38] monitor: simplify monitor_qmp_respond() Marc-André Lureau
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 15/38] qmp: pass and return a QDict to qmp_dispatch() Marc-André Lureau
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 16/38] qmp: move 'id' copy " Marc-André Lureau
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 17/38] qmp: constify qmp_is_oob() Marc-André Lureau
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 18/38] qmp: add QmpSession Marc-André Lureau
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 19/38] QmpSession: add a return_cb Marc-André Lureau
2018-03-26 15:08 ` Marc-André Lureau [this message]
2018-03-26 15:08 ` [Qemu-devel] [PATCH v3 21/38] QmpSession: add a dispatch callback Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 22/38] monitor: use QmpSession parsing and common dispatch code Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 23/38] QmpSession: introduce QmpReturn Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 24/38] qmp: remove qmp_build_error_object() Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 25/38] qmp: remove need for qobject_from_jsonf() Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 26/38] qmp: fold do_qmp_dispatch() in qmp_dispatch() Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 27/38] QmpSession: keep a queue of pending commands Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 28/38] QmpSession: return orderly Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 29/38] qmp: introduce asynchronous command type Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 30/38] scripts: learn 'async' qapi commands Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 31/38] qmp: add qmp_return_is_cancelled() Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 32/38] monitor: add qmp_return_get_monitor() Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 33/38] console: graphic_hw_update return true if async Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 34/38] console: add graphic_hw_update_done() Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 35/38] console: make screendump asynchronous Marc-André Lureau
2018-04-12 14:48   ` Dr. David Alan Gilbert
2018-04-19 16:05     ` Marc-André Lureau
2019-04-09 14:06     ` Marc-André Lureau
2019-04-09 14:06       ` Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 36/38] monitor: start making qmp_human_monitor_command() asynchronous Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 37/38] monitor: teach HMP about asynchronous commands Marc-André Lureau
2018-03-26 15:09 ` [Qemu-devel] [PATCH v3 38/38] hmp: call the asynchronous QMP screendump to fix outdated/glitches Marc-André Lureau
2018-03-26 17:24 ` [Qemu-devel] [PATCH v3 00/38] RFC: monitor: add asynchronous command type Dr. David Alan Gilbert
2018-03-26 17:30   ` Marc-André Lureau
2018-03-26 17:43 ` no-reply
2018-03-26 17:55 ` no-reply
2018-04-04  9:34 ` Stefan Hajnoczi
2018-04-04 10:01   ` Marc-André Lureau
2018-04-04 13:45 ` Eric Blake
2018-04-04 13:57   ` Marc-André Lureau
2018-07-05 13:05 ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180326150916.9602-21-marcandre.lureau@redhat.com \
    --to=marcandre.lureau@redhat.com \
    --cc=armbru@redhat.com \
    --cc=crosa@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=eblake@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.