qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] sane char device writes?
@ 2016-11-23 18:09 Michal Suchánek
  2016-11-24  7:51 ` Thomas Huth
  0 siblings, 1 reply; 5+ messages in thread
From: Michal Suchánek @ 2016-11-23 18:09 UTC (permalink / raw)
  To: qemu-devel

Hello,

I have reported the issue with qemu aborting in spapr_vty.c because
gtk.c submitted more data than can be sent to the emulated serial port.

While the abort has been resolved and spapr_vty.c should truncate the
data now getting the data through is still not possible.

Looking in the code I see that console.c has this code (which is only
piece of code in UI corresponding the the gtk part I found):

static void kbd_send_chars(void *opaque)
{
    QemuConsole *s = opaque;
    int len;
    uint8_t buf[16];

    len = qemu_chr_be_can_write(s->chr);
    if (len > s->out_fifo.count)
        len = s->out_fifo.count;
    if (len > 0) {
        if (len > sizeof(buf))
            len = sizeof(buf);
        qemu_fifo_read(&s->out_fifo, buf, len);
        qemu_chr_be_write(s->chr, buf, len);
    }
    /* characters are pending: we send them a bit later (XXX:
       horrible, should change char device API) */
    if (s->out_fifo.count > 0) {
        timer_mod(s->kbd_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
    + 1); }
}

The corresponding piece of code in gtk.c is AFAICT

static gboolean  (VteTerminal *terminal, gchar *text, guint size,
                         gpointer user_data)
{
    VirtualConsole *vc = user_data;

    if (vc->vte.echo) {
        VteTerminal *term = VTE_TERMINAL(vc->vte.terminal);
        int i;
        for (i = 0; i < size; i++) {
            uint8_t c = text[i];
            if (c >= 128 || isprint(c)) {
                /* 8-bit characters are considered printable.  */
                vte_terminal_feed(term, &text[i], 1);
            } else if (c == '\r' || c == '\n') {
                vte_terminal_feed(term, "\r\n", 2);
            } else {
                char ctrl[2] = { '^', 0};
                ctrl[1] = text[i] ^ 64;
                vte_terminal_feed(term, ctrl, 2);
            }
        }
    }

    qemu_chr_be_write(vc->vte.chr, (uint8_t  *)text, (unsigned
    int)size); return TRUE;
}

meaning there is no loop to split the submitted text buffer.

gd_vc_in is VTE callback handling input so I suspect it either handles
it or not and it cannot say it handled only part of the "commit" event.

So for this to work an extra buffer would have to be stored in gtk.c
somewhere, and possibly similar timer trick used as in console.c

Any ideas how to do this without introducing too much insanity?

Presumably using a GTK timer for repeating gd_vc_in the handler would
run in the same GTK UI thread as the "commit" signal handler and
excessive locking would not be required.

The data passed to gd_vc_in is presumably freed when it ends so it
would have to be copied somewhere. It's quite possible to create a
static list in gd_vc_in or some extra field in VirtualConsole.

Thanks

Michal

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-11-28 16:01 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-23 18:09 [Qemu-devel] sane char device writes? Michal Suchánek
2016-11-24  7:51 ` Thomas Huth
2016-11-25 16:16   ` Paolo Bonzini
2016-11-28 15:53     ` Michal Suchánek
2016-11-28 16:00       ` Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).