This fixes a thread race involving the monitor in monitor_qmp_event and monitor_qapi_event_emit .
Signed-off-by: Marc Morcos <[email protected]> --- monitor/monitor.c | 11 ++++++++++- monitor/qmp.c | 6 ++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/monitor/monitor.c b/monitor/monitor.c index c5a5d30877..4bfd72939d 100644 --- a/monitor/monitor.c +++ b/monitor/monitor.c @@ -338,6 +338,7 @@ static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict) { Monitor *mon; MonitorQMP *qmp_mon; + bool do_send = false; trace_monitor_protocol_event_emit(event, qdict); QTAILQ_FOREACH(mon, &mon_list, entry) { @@ -346,7 +347,15 @@ static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict) } qmp_mon = container_of(mon, MonitorQMP, common); - if (qmp_mon->commands != &qmp_cap_negotiation_commands) { + do_send = false; + + WITH_QEMU_LOCK_GUARD(&mon->mon_lock) { + if (qmp_mon->commands != &qmp_cap_negotiation_commands) { + do_send = true; + } + } + + if (do_send) { qmp_send_response(qmp_mon, qdict); } } diff --git a/monitor/qmp.c b/monitor/qmp.c index cb99a12d94..e1419a9efa 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -462,8 +462,10 @@ static void monitor_qmp_event(void *opaque, QEMUChrEvent event) switch (event) { case CHR_EVENT_OPENED: - mon->commands = &qmp_cap_negotiation_commands; - monitor_qmp_caps_reset(mon); + WITH_QEMU_LOCK_GUARD(&mon->common.mon_lock) { + mon->commands = &qmp_cap_negotiation_commands; + monitor_qmp_caps_reset(mon); + } data = qmp_greeting(mon); qmp_send_response(mon, data); qobject_unref(data); -- 2.52.0.239.gd5f0c6e74e-goog
