qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]