Add input buffer to mux chr (patch by Tristan Gingold).

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3735 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
balrog 2007-11-25 00:55:06 +00:00
parent 1fc678cc72
commit bd9bdce694
6 changed files with 46 additions and 3 deletions

43
vl.c
View file

@ -1594,6 +1594,11 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
s->chr_read(s->handler_opaque, buf, len);
}
void qemu_chr_accept_input(CharDriverState *s)
{
if (s->chr_accept_input)
s->chr_accept_input(s);
}
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
{
@ -1645,12 +1650,17 @@ static CharDriverState *qemu_chr_open_null(void)
static int term_timestamps;
static int64_t term_timestamps_start;
#define MAX_MUX 4
#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */
#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
typedef struct {
IOCanRWHandler *chr_can_read[MAX_MUX];
IOReadHandler *chr_read[MAX_MUX];
IOEventHandler *chr_event[MAX_MUX];
void *ext_opaque[MAX_MUX];
CharDriverState *drv;
unsigned char buffer[MUX_BUFFER_SIZE];
int prod;
int cons;
int mux_cnt;
int term_got_escape;
int max_size;
@ -1779,12 +1789,28 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
return 0;
}
static void mux_chr_accept_input(CharDriverState *chr)
{
int m = chr->focus;
MuxDriver *d = chr->opaque;
while (d->prod != d->cons &&
d->chr_can_read[m] &&
d->chr_can_read[m](d->ext_opaque[m])) {
d->chr_read[m](d->ext_opaque[m],
&d->buffer[d->cons++ & MUX_BUFFER_MASK], 1);
}
}
static int mux_chr_can_read(void *opaque)
{
CharDriverState *chr = opaque;
MuxDriver *d = chr->opaque;
if ((d->prod - d->cons) < MUX_BUFFER_SIZE)
return 1;
if (d->chr_can_read[chr->focus])
return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
return 0;
}
@ -1792,10 +1818,20 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
{
CharDriverState *chr = opaque;
MuxDriver *d = chr->opaque;
int m = chr->focus;
int i;
mux_chr_accept_input (opaque);
for(i = 0; i < size; i++)
if (mux_proc_byte(chr, d, buf[i]))
d->chr_read[chr->focus](d->ext_opaque[chr->focus], &buf[i], 1);
if (mux_proc_byte(chr, d, buf[i])) {
if (d->prod == d->cons &&
d->chr_can_read[m] &&
d->chr_can_read[m](d->ext_opaque[m]))
d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
else
d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i];
}
}
static void mux_chr_event(void *opaque, int event)
@ -1850,6 +1886,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
chr->focus = -1;
chr->chr_write = mux_chr_write;
chr->chr_update_read_handler = mux_chr_update_read_handler;
chr->chr_accept_input = mux_chr_accept_input;
return chr;
}