monitor: fix muxing

make the mux driver send mux_in and mux_out events when switching
focus while hooking up more handlers.

stop using CharDriverState->focus in monitor.c, track state using
the mux events instead.  This also removes the implicit assumtion
that a muxed monitor allways has mux channel 0.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Gerd Hoffmann 2009-09-10 10:58:54 +02:00 committed by Anthony Liguori
parent 06113719be
commit a7aec5da4d
2 changed files with 28 additions and 11 deletions

View file

@ -85,6 +85,8 @@ struct mon_fd_t {
struct Monitor { struct Monitor {
CharDriverState *chr; CharDriverState *chr;
int mux_out;
int reset_seen;
int flags; int flags;
int suspend_cnt; int suspend_cnt;
uint8_t outbuf[1024]; uint8_t outbuf[1024];
@ -129,7 +131,7 @@ static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
void monitor_flush(Monitor *mon) void monitor_flush(Monitor *mon)
{ {
if (mon && mon->outbuf_index != 0 && mon->chr->focus == 0) { if (mon && mon->outbuf_index != 0 && !mon->mux_out) {
qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index); qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index);
mon->outbuf_index = 0; mon->outbuf_index = 0;
} }
@ -3111,23 +3113,36 @@ static void monitor_event(void *opaque, int event)
switch (event) { switch (event) {
case CHR_EVENT_MUX_IN: case CHR_EVENT_MUX_IN:
readline_restart(mon->rs); mon->mux_out = 0;
monitor_resume(mon); if (mon->reset_seen) {
monitor_flush(mon); readline_restart(mon->rs);
monitor_resume(mon);
monitor_flush(mon);
} else {
mon->suspend_cnt = 0;
}
break; break;
case CHR_EVENT_MUX_OUT: case CHR_EVENT_MUX_OUT:
if (mon->suspend_cnt == 0) if (mon->reset_seen) {
monitor_printf(mon, "\n"); if (mon->suspend_cnt == 0) {
monitor_flush(mon); monitor_printf(mon, "\n");
monitor_suspend(mon); }
monitor_flush(mon);
monitor_suspend(mon);
} else {
mon->suspend_cnt++;
}
mon->mux_out = 1;
break; break;
case CHR_EVENT_RESET: case CHR_EVENT_RESET:
monitor_printf(mon, "QEMU %s monitor - type 'help' for more " monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
"information\n", QEMU_VERSION); "information\n", QEMU_VERSION);
if (mon->chr->focus == 0) if (!mon->mux_out) {
readline_show_prompt(mon->rs); readline_show_prompt(mon->rs);
}
mon->reset_seen = 1;
break; break;
} }
} }
@ -3155,8 +3170,6 @@ void monitor_init(CharDriverState *chr, int flags)
mon->chr = chr; mon->chr = chr;
mon->flags = flags; mon->flags = flags;
if (mon->chr->focus != 0)
mon->suspend_cnt = 1; /* mux'ed monitors start suspended */
if (flags & MONITOR_USE_READLINE) { if (flags & MONITOR_USE_READLINE) {
mon->rs = readline_init(mon, monitor_find_completion); mon->rs = readline_init(mon, monitor_find_completion);
monitor_read_command(mon, 0); monitor_read_command(mon, 0);

View file

@ -456,8 +456,12 @@ static void mux_chr_update_read_handler(CharDriverState *chr)
qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read, qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
mux_chr_event, chr); mux_chr_event, chr);
} }
if (chr->focus != -1) {
mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_OUT);
}
chr->focus = d->mux_cnt; chr->focus = d->mux_cnt;
d->mux_cnt++; d->mux_cnt++;
mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_IN);
} }
static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)