[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 07/25] qmp: introduce async command type
From: |
Marc-André Lureau |
Subject: |
[Qemu-devel] [PATCH v2 07/25] qmp: introduce async command type |
Date: |
Wed, 18 Jan 2017 20:03:14 +0400 |
Qemu used to have command types, but it was removed in
42a502a7a60632234f0dd5028924926a7eac6c94. Add it back, and add a new
type of command, QmpCommandFuncAsync: they can return later thanks to
QmpReturn. This commit introduces the new types and register functions.
Signed-off-by: Marc-André Lureau <address@hidden>
---
include/qapi/qmp/dispatch.h | 14 +++++++++++++-
qapi/qmp-dispatch.c | 21 ++++++++++++++-------
qapi/qmp-registry.c | 25 ++++++++++++++++++++++---
3 files changed, 49 insertions(+), 11 deletions(-)
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index bc64d4ed15..e13e381834 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -35,6 +35,12 @@ struct QmpClient {
};
typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
+typedef void (QmpCommandFuncAsync)(QDict *, QmpReturn *);
+
+typedef enum QmpCommandType {
+ QCT_NORMAL,
+ QCT_ASYNC,
+} QmpCommandType;
typedef enum QmpCommandOptions
{
@@ -44,8 +50,12 @@ typedef enum QmpCommandOptions
typedef struct QmpCommand
{
+ QmpCommandType type;
const char *name;
- QmpCommandFunc *fn;
+ union {
+ QmpCommandFunc *fn;
+ QmpCommandFuncAsync *fn_async;
+ };
QmpCommandOptions options;
QTAILQ_ENTRY(QmpCommand) node;
bool enabled;
@@ -53,6 +63,8 @@ typedef struct QmpCommand
void qmp_register_command(const char *name, QmpCommandFunc *fn,
QmpCommandOptions options);
+void qmp_register_async_command(const char *name, QmpCommandFuncAsync *fn,
+ QmpCommandOptions options);
void qmp_unregister_command(const char *name);
QmpCommand *qmp_find_command(const char *name);
void qmp_client_init(QmpClient *client, QmpDispatchReturn *return_cb);
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 6ceece5ef0..26f0a674ae 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -95,13 +95,20 @@ static QObject *do_qmp_dispatch(QObject *request, QmpReturn
*qret, Error **errp)
QINCREF(args);
}
- cmd->fn(args, &ret, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- } else if (cmd->options & QCO_NO_SUCCESS_RESP) {
- g_assert(!ret);
- } else if (!ret) {
- ret = QOBJECT(qdict_new());
+ switch (cmd->type) {
+ case QCT_NORMAL:
+ cmd->fn(args, &ret, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ } else if (cmd->options & QCO_NO_SUCCESS_RESP) {
+ g_assert(!ret);
+ } else if (!ret) {
+ ret = QOBJECT(qdict_new());
+ }
+ break;
+ case QCT_ASYNC:
+ cmd->fn_async(args, qret);
+ break;
}
QDECREF(args);
diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
index e8053686f3..52b5f4cba0 100644
--- a/qapi/qmp-registry.c
+++ b/qapi/qmp-registry.c
@@ -18,16 +18,35 @@
static QTAILQ_HEAD(QmpCommandList, QmpCommand) qmp_commands =
QTAILQ_HEAD_INITIALIZER(qmp_commands);
-void qmp_register_command(const char *name, QmpCommandFunc *fn,
- QmpCommandOptions options)
+static QmpCommand *qmp_command_new(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(&qmp_commands, cmd, node);
+
+ return cmd;
+}
+
+void qmp_register_command(const char *name, QmpCommandFunc *fn,
+ QmpCommandOptions options)
+{
+ QmpCommand *cmd = qmp_command_new(name, options);
+
+ cmd->type = QCT_NORMAL;
+ cmd->fn = fn;
+}
+
+void qmp_register_async_command(const char *name, QmpCommandFuncAsync *fn,
+ QmpCommandOptions options)
+{
+ QmpCommand *cmd = qmp_command_new(name, options);
+
+ cmd->type = QCT_ASYNC;
+ cmd->fn_async = fn;
}
void qmp_unregister_command(const char *name)
--
2.11.0.295.gd7dffce1c
- [Qemu-devel] [PATCH v2 00/25] qmp: add async command type, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 01/25] tests: start generic qemu-qmp tests, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 02/25] tests: change /0.15/* tests to /qmp/*, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 03/25] qmp: teach qmp_dispatch() to take a pre-filled QDict, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 04/25] qmp: use a return callback for the command reply, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 05/25] qmp: add QmpClient, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 06/25] qmp: add qmp_return_is_cancelled(), Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 08/25] qapi: ignore top-level 'id' field, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 07/25] qmp: introduce async command type,
Marc-André Lureau <=
- [Qemu-devel] [PATCH v2 09/25] qmp: take 'id' from request, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 10/25] qmp: check that async command have an 'id', Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 11/25] scripts: learn 'async' qapi commands, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 12/25] tests: add dispatch async tests, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 13/25] monitor: add 'async' capability, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 14/25] monitor: add !qmp pre-conditions, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 15/25] monitor: suspend when running async and client has no async, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 16/25] qmp: update qmp-spec about async capability, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 17/25] qtest: add qtest-timeout, Marc-André Lureau, 2017/01/18
- [Qemu-devel] [PATCH v2 19/25] tests: add tests for async and non-async clients, Marc-André Lureau, 2017/01/18