diff options
author | Peter Maydell | 2018-06-30 18:30:09 +0200 |
---|---|---|
committer | Peter Maydell | 2018-06-30 18:30:09 +0200 |
commit | e3800998e66c13b24d8cc8a06fdcc8d03cd408fc (patch) | |
tree | 7a4eeaf3ce8c8c362403381ecc4f7bd6228105b0 /monitor.c | |
parent | Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' int... (diff) | |
parent | docs: mention shared state protect for OOB (diff) | |
download | qemu-e3800998e66c13b24d8cc8a06fdcc8d03cd408fc.tar.gz qemu-e3800998e66c13b24d8cc8a06fdcc8d03cd408fc.tar.xz 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
@@ -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); |