diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2013-04-05 08:55:14 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2013-04-05 08:55:14 -0500 |
commit | 150a470b64c548b7539ea47526f345f15ebac355 (patch) | |
tree | 5695dfe2c53f2d958e7999fb8e9d48a8b67c38b2 | |
parent | d05ef160453e98546a4197496dc8a3cb2defac53 (diff) | |
parent | 4bf0bb8014ac2ac61b1004f5d92b2a4594d48017 (diff) |
Merge remote-tracking branch 'luiz/queue/qmp' into staging
# By Luiz Capitulino
# Via Luiz Capitulino
* luiz/queue/qmp:
chardev: drop the Memory chardev driver
hmp: human-monitor-command: stop using the Memory chardev driver
Monitor: Make output buffer dynamic
qstring: add qstring_get_length()
-rw-r--r-- | include/qapi/qmp/qstring.h | 1 | ||||
-rw-r--r-- | monitor.c | 60 | ||||
-rw-r--r-- | qemu-char.c | 64 | ||||
-rw-r--r-- | qobject/qstring.c | 8 |
4 files changed, 44 insertions, 89 deletions
diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h index 0e690f4849..1bc3666107 100644 --- a/include/qapi/qmp/qstring.h +++ b/include/qapi/qmp/qstring.h @@ -26,6 +26,7 @@ typedef struct QString { QString *qstring_new(void); QString *qstring_from_str(const char *str); QString *qstring_from_substr(const char *str, int start, int end); +size_t qstring_get_length(const QString *qstring); const char *qstring_get_str(const QString *qstring); void qstring_append_int(QString *qstring, int64_t value); void qstring_append(QString *qstring, const char *str); @@ -188,8 +188,8 @@ struct Monitor { int reset_seen; int flags; int suspend_cnt; - uint8_t outbuf[1024]; - int outbuf_index; + bool skip_flush; + QString *outbuf; ReadLineState *rs; MonitorControl *mc; CPUArchState *mon_cpu; @@ -271,45 +271,56 @@ static gboolean monitor_unblocked(GIOChannel *chan, GIOCondition cond, void monitor_flush(Monitor *mon) { int rc; + size_t len; + const char *buf; + + if (mon->skip_flush) { + return; + } - if (mon && mon->outbuf_index != 0 && !mon->mux_out) { - rc = qemu_chr_fe_write(mon->chr, mon->outbuf, mon->outbuf_index); - if (rc == mon->outbuf_index) { + buf = qstring_get_str(mon->outbuf); + len = qstring_get_length(mon->outbuf); + + if (mon && len && !mon->mux_out) { + rc = qemu_chr_fe_write(mon->chr, (const uint8_t *) buf, len); + if (rc == len) { /* all flushed */ - mon->outbuf_index = 0; + QDECREF(mon->outbuf); + mon->outbuf = qstring_new(); return; } if (rc > 0) { /* partinal write */ - memmove(mon->outbuf, mon->outbuf + rc, mon->outbuf_index - rc); - mon->outbuf_index -= rc; + QString *tmp = qstring_from_str(buf + rc); + QDECREF(mon->outbuf); + mon->outbuf = tmp; } qemu_chr_fe_add_watch(mon->chr, G_IO_OUT, monitor_unblocked, mon); } } -/* flush at every end of line or if the buffer is full */ +/* flush at every end of line */ static void monitor_puts(Monitor *mon, const char *str) { char c; for(;;) { - assert(mon->outbuf_index < sizeof(mon->outbuf) - 1); c = *str++; if (c == '\0') break; - if (c == '\n') - mon->outbuf[mon->outbuf_index++] = '\r'; - mon->outbuf[mon->outbuf_index++] = c; - if (mon->outbuf_index >= (sizeof(mon->outbuf) - 1) - || c == '\n') + if (c == '\n') { + qstring_append_chr(mon->outbuf, '\r'); + } + qstring_append_chr(mon->outbuf, c); + if (c == '\n') { monitor_flush(mon); + } } } void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { - char buf[4096]; + char *buf; if (!mon) return; @@ -318,8 +329,9 @@ void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) return; } - vsnprintf(buf, sizeof(buf), fmt, ap); + buf = g_strdup_vprintf(fmt, ap); monitor_puts(mon, buf); + g_free(buf); } void monitor_printf(Monitor *mon, const char *fmt, ...) @@ -668,11 +680,10 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, { char *output = NULL; Monitor *old_mon, hmp; - CharDriverState mchar; memset(&hmp, 0, sizeof(hmp)); - qemu_chr_init_mem(&mchar); - hmp.chr = &mchar; + hmp.outbuf = qstring_new(); + hmp.skip_flush = true; old_mon = cur_mon; cur_mon = &hmp; @@ -690,16 +701,14 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, handle_user_command(&hmp, command_line); cur_mon = old_mon; - if (qemu_chr_mem_osize(hmp.chr) > 0) { - QString *str = qemu_chr_mem_to_qs(hmp.chr); - output = g_strdup(qstring_get_str(str)); - QDECREF(str); + if (qstring_get_length(hmp.outbuf) > 0) { + output = g_strdup(qstring_get_str(hmp.outbuf)); } else { output = g_strdup(""); } out: - qemu_chr_close_mem(hmp.chr); + QDECREF(hmp.outbuf); return output; } @@ -4749,6 +4758,7 @@ void monitor_init(CharDriverState *chr, int flags) } mon = g_malloc0(sizeof(*mon)); + mon->outbuf = qstring_new(); mon->chr = chr; mon->flags = flags; diff --git a/qemu-char.c b/qemu-char.c index e5eb8dd2ef..0f7f32decb 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2796,70 +2796,6 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) return NULL; } -/***********************************************************/ -/* Memory chardev */ -typedef struct { - size_t outbuf_size; - size_t outbuf_capacity; - uint8_t *outbuf; -} MemoryDriver; - -static int mem_chr_write(CharDriverState *chr, const uint8_t *buf, int len) -{ - MemoryDriver *d = chr->opaque; - - /* TODO: the QString implementation has the same code, we should - * introduce a generic way to do this in cutils.c */ - if (d->outbuf_capacity < d->outbuf_size + len) { - /* grow outbuf */ - d->outbuf_capacity += len; - d->outbuf_capacity *= 2; - d->outbuf = g_realloc(d->outbuf, d->outbuf_capacity); - } - - memcpy(d->outbuf + d->outbuf_size, buf, len); - d->outbuf_size += len; - - return len; -} - -void qemu_chr_init_mem(CharDriverState *chr) -{ - MemoryDriver *d; - - d = g_malloc(sizeof(*d)); - d->outbuf_size = 0; - d->outbuf_capacity = 4096; - d->outbuf = g_malloc0(d->outbuf_capacity); - - memset(chr, 0, sizeof(*chr)); - chr->opaque = d; - chr->chr_write = mem_chr_write; -} - -QString *qemu_chr_mem_to_qs(CharDriverState *chr) -{ - MemoryDriver *d = chr->opaque; - return qstring_from_substr((char *) d->outbuf, 0, d->outbuf_size - 1); -} - -/* NOTE: this driver can not be closed with qemu_chr_delete()! */ -void qemu_chr_close_mem(CharDriverState *chr) -{ - MemoryDriver *d = chr->opaque; - - g_free(d->outbuf); - g_free(chr->opaque); - chr->opaque = NULL; - chr->chr_write = NULL; -} - -size_t qemu_chr_mem_osize(const CharDriverState *chr) -{ - const MemoryDriver *d = chr->opaque; - return d->outbuf_size; -} - /*********************************************************/ /* Ring buffer chardev */ diff --git a/qobject/qstring.c b/qobject/qstring.c index 5f7376c336..607b7a142c 100644 --- a/qobject/qstring.c +++ b/qobject/qstring.c @@ -32,6 +32,14 @@ QString *qstring_new(void) } /** + * qstring_get_length(): Get the length of a QString + */ +size_t qstring_get_length(const QString *qstring) +{ + return qstring->length; +} + +/** * qstring_from_substr(): Create a new QString from a C string substring * * Return string reference |