Add a new type of command, QmpCommandFuncAsync: those commands can return later thanks to QmpReturn. This commit introduces the new type and register function and teach qmp_dipatch() to call it without qmp_return().
Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> --- include/qapi/qmp/dispatch.h | 9 ++++++++- qapi/qmp-dispatch.c | 4 +++- qapi/qmp-registry.c | 27 ++++++++++++++++++++++++--- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index f6db06c164..e426317346 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -21,18 +21,23 @@ typedef struct QmpReturn QmpReturn; typedef void (QmpCommandFunc)(QDict *, QObject **, Error **); +typedef void (QmpCommandAsyncFunc)(QDict *, QmpReturn *); typedef enum QmpCommandOptions { QCO_NO_OPTIONS = 0x0, QCO_NO_SUCCESS_RESP = (1U << 0), QCO_ALLOW_OOB = (1U << 1), + QCO_ASYNC = (1U << 2), } QmpCommandOptions; typedef struct QmpCommand { const char *name; - QmpCommandFunc *fn; + union { + QmpCommandFunc *fn; + QmpCommandAsyncFunc *async_fn; + }; QmpCommandOptions options; QTAILQ_ENTRY(QmpCommand) node; bool enabled; @@ -88,6 +93,8 @@ void qmp_return_error(QmpReturn *qret, Error *err); void qmp_register_command(QmpCommandList *cmds, const char *name, QmpCommandFunc *fn, QmpCommandOptions options); +void qmp_register_async_command(QmpCommandList *cmds, const char *name, + QmpCommandAsyncFunc *fn, QmpCommandOptions options); void qmp_unregister_command(QmpCommandList *cmds, const char *name); QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name); diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index aa8b71a2c0..f7d9931734 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -195,7 +195,9 @@ void qmp_dispatch(QmpSession *session, QDict *req) QINCREF(args); } - { + if (cmd->options & QCO_ASYNC) { + cmd->async_fn(args, qmp_return_new(session, req)); + } else { QObject *ret = NULL; cmd->fn(args, &ret, &err); if (err || cmd->options & QCO_NO_SUCCESS_RESP) { diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c index 5af484cd9a..180b1c1e69 100644 --- a/qapi/qmp-registry.c +++ b/qapi/qmp-registry.c @@ -15,16 +15,37 @@ #include "qemu/osdep.h" #include "qapi/qmp/dispatch.h" -void qmp_register_command(QmpCommandList *cmds, const char *name, - QmpCommandFunc *fn, QmpCommandOptions options) + +static QmpCommand *qmp_command_new(QmpCommandList *cmds, const char *name, + QmpCommandOptions options) { QmpCommand *cmd = g_malloc0(sizeof(*cmd)); cmd->name = name; - cmd->fn = fn; cmd->enabled = true; cmd->options = options; QTAILQ_INSERT_TAIL(cmds, cmd, node); + + return cmd; +} + + +void qmp_register_command(QmpCommandList *cmds, const char *name, + QmpCommandFunc *fn, QmpCommandOptions options) +{ + QmpCommand *cmd = qmp_command_new(cmds, name, options); + + assert(!(options & QCO_ASYNC)); + cmd->fn = fn; +} + +void qmp_register_async_command(QmpCommandList *cmds, const char *name, + QmpCommandAsyncFunc *fn, QmpCommandOptions options) +{ + QmpCommand *cmd = qmp_command_new(cmds, name, options); + + assert(options & QCO_ASYNC); + cmd->async_fn = fn; } void qmp_unregister_command(QmpCommandList *cmds, const char *name) -- 2.17.0.rc1.1.g4c4f2b46a3