diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2018-06-30 17:30:09 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2018-06-30 17:30:09 +0100 |
| commit | e3800998e66c13b24d8cc8a06fdcc8d03cd408fc (patch) | |
| tree | 7a4eeaf3ce8c8c362403381ecc4f7bd6228105b0 /monitor.c | |
| parent | 6f4fa0998fd13bd8a533f38ee69774ecad6911b6 (diff) | |
| parent | 4bfa7974d90a0cbad29c0a27334d02cbd37bb23d (diff) | |
| download | focaccia-qemu-e3800998e66c13b24d8cc8a06fdcc8d03cd408fc.tar.gz focaccia-qemu-e3800998e66c13b24d8cc8a06fdcc8d03cd408fc.zip | |
Merge remote-tracking branch 'remotes/armbru/tags/pull-monitor-2018-06-30' into staging
Monitor patches for 2018-06-30 # gpg: Signature made Sat 30 Jun 2018 17:22:12 BST # gpg: using RSA key 3870B400EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-monitor-2018-06-30: docs: mention shared state protect for OOB tests: iotests: drop some stderr line monitor: flush qmp responses when CLOSED monitor: rename *_pop_one to *_pop_any chardev: comment details for CLOSED event Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'monitor.c')
| -rw-r--r-- | monitor.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/monitor.c b/monitor.c index 7b473aad1f..567668a0e7 100644 --- a/monitor.c +++ b/monitor.c @@ -541,37 +541,54 @@ struct QMPResponse { }; typedef struct QMPResponse QMPResponse; +static QObject *monitor_qmp_response_pop_one(Monitor *mon) +{ + QObject *data; + + qemu_mutex_lock(&mon->qmp.qmp_queue_lock); + data = g_queue_pop_head(mon->qmp.qmp_responses); + qemu_mutex_unlock(&mon->qmp.qmp_queue_lock); + + return data; +} + +static void monitor_qmp_response_flush(Monitor *mon) +{ + QObject *data; + + while ((data = monitor_qmp_response_pop_one(mon))) { + monitor_json_emitter_raw(mon, data); + qobject_unref(data); + } +} + /* - * Return one QMPResponse. The response is only valid if - * response.data is not NULL. + * Pop a QMPResponse from any monitor's response queue into @response. + * Return false if all the queues are empty; else true. */ -static QMPResponse monitor_qmp_response_pop_one(void) +static bool monitor_qmp_response_pop_any(QMPResponse *response) { Monitor *mon; QObject *data = NULL; qemu_mutex_lock(&monitor_lock); QTAILQ_FOREACH(mon, &mon_list, entry) { - qemu_mutex_lock(&mon->qmp.qmp_queue_lock); - data = g_queue_pop_head(mon->qmp.qmp_responses); - qemu_mutex_unlock(&mon->qmp.qmp_queue_lock); + data = monitor_qmp_response_pop_one(mon); if (data) { + response->mon = mon; + response->data = data; break; } } qemu_mutex_unlock(&monitor_lock); - return (QMPResponse) { .mon = mon, .data = data }; + return data != NULL; } static void monitor_qmp_bh_responder(void *opaque) { QMPResponse response; - while (true) { - response = monitor_qmp_response_pop_one(); - if (!response.data) { - break; - } + while (monitor_qmp_response_pop_any(&response)) { monitor_json_emitter_raw(response.mon, response.data); qobject_unref(response.data); } @@ -4199,7 +4216,7 @@ static void monitor_qmp_dispatch_one(QMPRequest *req_obj) * when we process one request on a specific monitor, we put that * monitor to the end of mon_list queue. */ -static QMPRequest *monitor_qmp_requests_pop_one(void) +static QMPRequest *monitor_qmp_requests_pop_any(void) { QMPRequest *req_obj = NULL; Monitor *mon; @@ -4231,7 +4248,7 @@ static QMPRequest *monitor_qmp_requests_pop_one(void) static void monitor_qmp_bh_dispatcher(void *data) { - QMPRequest *req_obj = monitor_qmp_requests_pop_one(); + QMPRequest *req_obj = monitor_qmp_requests_pop_any(); if (req_obj) { trace_monitor_qmp_cmd_in_band(qobject_get_try_str(req_obj->id) ?: ""); @@ -4458,6 +4475,13 @@ static void monitor_qmp_event(void *opaque, int event) mon_refcount++; break; case CHR_EVENT_CLOSED: + /* + * Note: this is only useful when the output of the chardev + * backend is still open. For example, when the backend is + * stdio, it's possible that stdout is still open when stdin + * is closed. + */ + monitor_qmp_response_flush(mon); monitor_qmp_cleanup_queues(mon); json_message_parser_destroy(&mon->qmp.parser); json_message_parser_init(&mon->qmp.parser, handle_qmp_command); |