monitor: let suspend_cnt be thread safe

Monitor code now can be run in more than one thread.  Let it be thread
safe when accessing suspend_cnt counter.

Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Message-Id: <20180309090006.10018-13-peterx@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Peter Xu 2018-03-09 16:59:55 +08:00 committed by Eric Blake
parent 546aa56674
commit df152fb950

View File

@ -194,7 +194,7 @@ struct Monitor {
CharBackend chr;
int reset_seen;
int flags;
int suspend_cnt;
int suspend_cnt; /* Needs to be accessed atomically */
bool skip_flush;
bool use_io_thr;
@ -3819,7 +3819,7 @@ static int monitor_can_read(void *opaque)
{
Monitor *mon = opaque;
return (mon->suspend_cnt == 0) ? 1 : 0;
return !atomic_mb_read(&mon->suspend_cnt);
}
/*
@ -3951,7 +3951,7 @@ int monitor_suspend(Monitor *mon)
{
if (!mon->rs)
return -ENOTTY;
mon->suspend_cnt++;
atomic_inc(&mon->suspend_cnt);
return 0;
}
@ -3959,9 +3959,10 @@ void monitor_resume(Monitor *mon)
{
if (!mon->rs)
return;
if (--mon->suspend_cnt == 0)
if (atomic_dec_fetch(&mon->suspend_cnt) == 0) {
readline_show_prompt(mon->rs);
}
}
static QObject *get_qmp_greeting(Monitor *mon)
{
@ -4025,19 +4026,19 @@ static void monitor_event(void *opaque, int event)
monitor_resume(mon);
monitor_flush(mon);
} else {
mon->suspend_cnt = 0;
atomic_mb_set(&mon->suspend_cnt, 0);
}
break;
case CHR_EVENT_MUX_OUT:
if (mon->reset_seen) {
if (mon->suspend_cnt == 0) {
if (atomic_mb_read(&mon->suspend_cnt) == 0) {
monitor_printf(mon, "\n");
}
monitor_flush(mon);
monitor_suspend(mon);
} else {
mon->suspend_cnt++;
atomic_inc(&mon->suspend_cnt);
}
qemu_mutex_lock(&mon->out_lock);
mon->mux_out = 1;