From: Marc-André Lureau <marcandre.lur...@redhat.com> In order to prepare for the async support, give an optionnal qdict for the dispatch call to be used for the reply. The qemu monitor will have the request "id" pre-filled.
Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> --- include/qapi/qmp/dispatch.h | 2 +- monitor.c | 24 ++++++++++-------------- qapi/qmp-dispatch.c | 5 ++--- qga/main.c | 2 +- tests/test-qmp-commands.c | 6 +++--- 5 files changed, 17 insertions(+), 22 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index e389697..96de3bf 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -44,7 +44,7 @@ typedef struct QmpCommand void qmp_register_command(const char *name, QmpCommandFunc *fn, QmpCommandOptions options); QmpCommand *qmp_find_command(const char *name); -QObject *qmp_dispatch(QObject *request); +QObject *qmp_dispatch(QObject *request, QDict *rsp); void qmp_disable_command(const char *name); void qmp_enable_command(const char *name); bool qmp_command_is_enabled(const QmpCommand *cmd); diff --git a/monitor.c b/monitor.c index 25f9608..d7ee509 100644 --- a/monitor.c +++ b/monitor.c @@ -3572,12 +3572,13 @@ static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp) static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) { - QObject *req, *rsp = NULL, *id = NULL; - QDict *qdict = NULL; + QObject *req, *rsp, *id = NULL; + QDict *qdict, *rqdict = qdict_new(); const char *cmd_name; Monitor *mon = cur_mon; Error *err = NULL; + rsp = QOBJECT(rqdict); req = json_parser_parse_err(tokens, NULL, &err); if (err || !req || qobject_type(req) != QTYPE_QDICT) { if (!err) { @@ -3592,8 +3593,11 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) } id = qdict_get(qdict, "id"); - qobject_incref(id); - qdict_del(qdict, "id"); + if (id) { + qobject_incref(id); + qdict_del(qdict, "id"); + qdict_put_obj(rqdict, "id", id); + } cmd_name = qdict_get_str(qdict, "execute"); trace_handle_qmp_command(mon, cmd_name); @@ -3602,26 +3606,18 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) goto err_out; } - rsp = qmp_dispatch(req); + rsp = qmp_dispatch(req, rqdict); err_out: if (err) { - qdict = qdict_new(); - qdict_put_obj(qdict, "error", qmp_build_error_object(err)); + qdict_put_obj(rqdict, "error", qmp_build_error_object(err)); error_free(err); - rsp = QOBJECT(qdict); } if (rsp) { - if (id) { - qdict_put_obj(qobject_to_qdict(rsp), "id", id); - id = NULL; - } - monitor_json_emitter(mon, rsp); } - qobject_decref(id); qobject_decref(rsp); qobject_decref(req); } diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 7bcc860..d2ae5f0 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -118,15 +118,14 @@ QObject *qmp_build_error_object(Error *err) error_get_pretty(err)); } -QObject *qmp_dispatch(QObject *request) +QObject *qmp_dispatch(QObject *request, QDict *rsp) { Error *err = NULL; QObject *ret; - QDict *rsp; ret = do_qmp_dispatch(request, &err); - rsp = qdict_new(); + rsp = rsp ?: qdict_new(); if (err) { qdict_put_obj(rsp, "error", qmp_build_error_object(err)); error_free(err); diff --git a/qga/main.c b/qga/main.c index d8e063a..bfcde0b 100644 --- a/qga/main.c +++ b/qga/main.c @@ -553,7 +553,7 @@ static void process_command(GAState *s, QDict *req) g_assert(req); g_debug("processing command"); - rsp = qmp_dispatch(QOBJECT(req)); + rsp = qmp_dispatch(QOBJECT(req), NULL); if (rsp) { ret = send_response(s, rsp); if (ret) { diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c index 886de98..068db21 100644 --- a/tests/test-qmp-commands.c +++ b/tests/test-qmp-commands.c @@ -85,7 +85,7 @@ static void test_dispatch_cmd(void) qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd"))); - resp = qmp_dispatch(QOBJECT(req)); + resp = qmp_dispatch(QOBJECT(req), NULL); assert(resp != NULL); assert(!qdict_haskey(qobject_to_qdict(resp), "error")); @@ -101,7 +101,7 @@ static void test_dispatch_cmd_error(void) qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2"))); - resp = qmp_dispatch(QOBJECT(req)); + resp = qmp_dispatch(QOBJECT(req), NULL); assert(resp != NULL); assert(qdict_haskey(qobject_to_qdict(resp), "error")); @@ -115,7 +115,7 @@ static QObject *test_qmp_dispatch(QDict *req) QDict *resp; QObject *ret; - resp_obj = qmp_dispatch(QOBJECT(req)); + resp_obj = qmp_dispatch(QOBJECT(req), NULL); assert(resp_obj); resp = qobject_to_qdict(resp_obj); assert(resp && !qdict_haskey(resp, "error")); -- 2.4.3