|
@@ -1056,12 +1056,26 @@ fail:
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+typedef struct HandleHmpCommandCo {
|
|
|
|
+ Monitor *mon;
|
|
|
|
+ const HMPCommand *cmd;
|
|
|
|
+ QDict *qdict;
|
|
|
|
+ bool done;
|
|
|
|
+} HandleHmpCommandCo;
|
|
|
|
+
|
|
|
|
+static void handle_hmp_command_co(void *opaque)
|
|
|
|
+{
|
|
|
|
+ HandleHmpCommandCo *data = opaque;
|
|
|
|
+ data->cmd->cmd(data->mon, data->qdict);
|
|
|
|
+ monitor_set_cur(qemu_coroutine_self(), NULL);
|
|
|
|
+ data->done = true;
|
|
|
|
+}
|
|
|
|
+
|
|
void handle_hmp_command(MonitorHMP *mon, const char *cmdline)
|
|
void handle_hmp_command(MonitorHMP *mon, const char *cmdline)
|
|
{
|
|
{
|
|
QDict *qdict;
|
|
QDict *qdict;
|
|
const HMPCommand *cmd;
|
|
const HMPCommand *cmd;
|
|
const char *cmd_start = cmdline;
|
|
const char *cmd_start = cmdline;
|
|
- Monitor *old_mon;
|
|
|
|
|
|
|
|
trace_handle_hmp_command(mon, cmdline);
|
|
trace_handle_hmp_command(mon, cmdline);
|
|
|
|
|
|
@@ -1080,10 +1094,23 @@ void handle_hmp_command(MonitorHMP *mon, const char *cmdline)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- /* old_mon is non-NULL when called from qmp_human_monitor_command() */
|
|
|
|
- old_mon = monitor_set_cur(qemu_coroutine_self(), &mon->common);
|
|
|
|
- cmd->cmd(&mon->common, qdict);
|
|
|
|
- monitor_set_cur(qemu_coroutine_self(), old_mon);
|
|
|
|
|
|
+ if (!cmd->coroutine) {
|
|
|
|
+ /* old_mon is non-NULL when called from qmp_human_monitor_command() */
|
|
|
|
+ Monitor *old_mon = monitor_set_cur(qemu_coroutine_self(), &mon->common);
|
|
|
|
+ cmd->cmd(&mon->common, qdict);
|
|
|
|
+ monitor_set_cur(qemu_coroutine_self(), old_mon);
|
|
|
|
+ } else {
|
|
|
|
+ HandleHmpCommandCo data = {
|
|
|
|
+ .mon = &mon->common,
|
|
|
|
+ .cmd = cmd,
|
|
|
|
+ .qdict = qdict,
|
|
|
|
+ .done = false,
|
|
|
|
+ };
|
|
|
|
+ Coroutine *co = qemu_coroutine_create(handle_hmp_command_co, &data);
|
|
|
|
+ monitor_set_cur(co, &mon->common);
|
|
|
|
+ aio_co_enter(qemu_get_aio_context(), co);
|
|
|
|
+ AIO_WAIT_WHILE(qemu_get_aio_context(), !data.done);
|
|
|
|
+ }
|
|
|
|
|
|
qobject_unref(qdict);
|
|
qobject_unref(qdict);
|
|
}
|
|
}
|