All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: wenchaoqemu@gmail.com, lcapitulino@redhat.com
Subject: [Qemu-devel] [PATCH 2.1 35/36] monitor: protect outbuf and mux_out with mutex
Date: Wed, 18 Jun 2014 08:43:59 +0200	[thread overview]
Message-ID: <1403073840-32603-36-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1403073840-32603-1-git-send-email-pbonzini@redhat.com>

This lets the block layer emit QMP events from outside the I/O thread.

Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 monitor.c | 45 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 9 deletions(-)

diff --git a/monitor.c b/monitor.c
index 66a1db7..2b97e4e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -191,13 +191,18 @@ typedef struct MonitorQAPIEventState {
 
 struct Monitor {
     CharDriverState *chr;
-    int mux_out;
     int reset_seen;
     int flags;
     int suspend_cnt;
     bool skip_flush;
+
+    QemuMutex out_lock;
     QString *outbuf;
-    guint watch;
+    guint out_watch;
+
+    /* Read under either BQL or out_lock, written with BQL+out_lock.  */
+    int mux_out;
+
     ReadLineState *rs;
     MonitorControl *mc;
     CPUState *mon_cpu;
@@ -270,17 +275,22 @@ int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
     }
 }
 
+static void monitor_flush_locked(Monitor *mon);
+
 static gboolean monitor_unblocked(GIOChannel *chan, GIOCondition cond,
                                   void *opaque)
 {
     Monitor *mon = opaque;
 
-    mon->watch = 0;
-    monitor_flush(mon);
+    qemu_mutex_lock(&mon->out_lock);
+    mon->out_watch = 0;
+    monitor_flush_locked(mon);
+    qemu_mutex_unlock(&mon->out_lock);
     return FALSE;
 }
 
-void monitor_flush(Monitor *mon)
+/* Called with mon->out_lock held.  */
+static void monitor_flush_locked(Monitor *mon)
 {
     int rc;
     size_t len;
@@ -307,18 +317,26 @@ void monitor_flush(Monitor *mon)
             QDECREF(mon->outbuf);
             mon->outbuf = tmp;
         }
-        if (mon->watch == 0) {
-            mon->watch = qemu_chr_fe_add_watch(mon->chr, G_IO_OUT,
-                                               monitor_unblocked, mon);
+        if (mon->out_watch == 0) {
+            mon->out_watch = qemu_chr_fe_add_watch(mon->chr, G_IO_OUT,
+                                                   monitor_unblocked, mon);
         }
     }
 }
 
+void monitor_flush(Monitor *mon)
+{
+    qemu_mutex_lock(&mon->out_lock);
+    monitor_flush_locked(mon);
+    qemu_mutex_unlock(&mon->out_lock);
+}
+
 /* flush at every end of line */
 static void monitor_puts(Monitor *mon, const char *str)
 {
     char c;
 
+    qemu_mutex_lock(&mon->out_lock);
     for(;;) {
         c = *str++;
         if (c == '\0')
@@ -328,9 +346,10 @@ static void monitor_puts(Monitor *mon, const char *str)
         }
         qstring_append_chr(mon->outbuf, c);
         if (c == '\n') {
-            monitor_flush(mon);
+            monitor_flush_locked(mon);
         }
     }
+    qemu_mutex_unlock(&mon->out_lock);
 }
 
 void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
@@ -581,6 +600,7 @@ static void handle_user_command(Monitor *mon, const char *cmdline);
 static void monitor_data_init(Monitor *mon)
 {
     memset(mon, 0, sizeof(Monitor));
+    qemu_mutex_init(&mon->out_lock);
     mon->outbuf = qstring_new();
     /* Use *mon_cmds by default. */
     mon->cmd_table = mon_cmds;
@@ -589,6 +609,7 @@ static void monitor_data_init(Monitor *mon)
 static void monitor_data_destroy(Monitor *mon)
 {
     QDECREF(mon->outbuf);
+    qemu_mutex_destroy(&mon->out_lock);
 }
 
 char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
@@ -616,11 +637,13 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
     handle_user_command(&hmp, command_line);
     cur_mon = old_mon;
 
+    qemu_mutex_lock(&hmp.out_lock);
     if (qstring_get_length(hmp.outbuf) > 0) {
         output = g_strdup(qstring_get_str(hmp.outbuf));
     } else {
         output = g_strdup("");
     }
+    qemu_mutex_unlock(&hmp.out_lock);
 
 out:
     monitor_data_destroy(&hmp);
@@ -5173,7 +5196,9 @@ static void monitor_event(void *opaque, int event)
 
     switch (event) {
     case CHR_EVENT_MUX_IN:
+        qemu_mutex_lock(&mon->out_lock);
         mon->mux_out = 0;
+        qemu_mutex_unlock(&mon->out_lock);
         if (mon->reset_seen) {
             readline_restart(mon->rs);
             monitor_resume(mon);
@@ -5193,7 +5218,9 @@ static void monitor_event(void *opaque, int event)
         } else {
             mon->suspend_cnt++;
         }
+        qemu_mutex_lock(&mon->out_lock);
         mon->mux_out = 1;
+        qemu_mutex_unlock(&mon->out_lock);
         break;
 
     case CHR_EVENT_OPENED:
-- 
1.9.3

  parent reply	other threads:[~2014-06-18  6:45 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 01/36] os-posix: include sys/time.h Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 02/36] qapi: Add includes from qapi/ as dependencies Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 03/36] qapi: add event helper functions Paolo Bonzini
2014-06-18 22:55   ` Wenchao Xia
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 04/36] qapi script: add event support Paolo Bonzini
2014-06-19 12:06   ` Eric Blake
2014-06-19 19:57   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 05/36] test: add test cases for qapi event Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 06/36] qapi: adjust existing defines Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 07/36] monitor: add an implemention of qapi event emit method Paolo Bonzini
2014-06-19  4:03   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 08/36] qapi: add new schema file qapi-event.json Paolo Bonzini
2014-06-19  4:04   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 09/36] qapi event: convert SHUTDOWN Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 10/36] qapi event: convert POWERDOWN Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 11/36] qapi event: convert RESET Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 12/36] qapi event: convert STOP Paolo Bonzini
2014-06-19 18:15   ` Luiz Capitulino
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 13/36] qapi event: convert RESUME Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 14/36] qapi event: convert SUSPEND Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 15/36] qapi event: convert SUSPEND_DISK Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 16/36] qapi event: convert WAKEUP Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 17/36] qapi event: convert RTC_CHANGE Paolo Bonzini
2014-06-19  4:06   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 18/36] qapi event: convert WATCHDOG Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 19/36] qapi event: convert DEVICE_DELETED Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 20/36] qapi event: convert DEVICE_TRAY_MOVED Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR Paolo Bonzini
2014-06-26 15:37   ` Markus Armbruster
2014-06-26 15:40     ` Paolo Bonzini
2014-06-26 15:44       ` Luiz Capitulino
2014-06-26 15:58       ` Markus Armbruster
2014-06-26 16:00         ` Luiz Capitulino
2014-06-27 12:21         ` Markus Armbruster
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 22/36] qapi event: convert BLOCK_IMAGE_CORRUPTED Paolo Bonzini
2014-06-19  4:09   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 23/36] qapi event: convert other BLOCK_JOB events Paolo Bonzini
2014-06-19  4:11   ` Eric Blake
2014-06-26 14:08   ` Markus Armbruster
2014-06-26 14:19     ` Paolo Bonzini
2014-06-26 14:24       ` Luiz Capitulino
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 24/36] qapi event: convert NIC_RX_FILTER_CHANGED Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 25/36] qapi event: convert VNC events Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 26/36] qapi event: convert SPICE events Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 27/36] qapi event: convert BALLOON_CHANGE Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 28/36] qapi event: convert GUEST_PANICKED Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 29/36] qapi event: convert QUORUM events Paolo Bonzini
2014-06-19  4:14   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 30/36] qapi event: clean up Paolo Bonzini
2014-06-19  4:17   ` Eric Blake
2014-06-19  8:00     ` Paolo Bonzini
2014-06-19 14:51       ` Luiz Capitulino
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 32/36] qemu-char: do not call chr_write directly Paolo Bonzini
2014-06-19 14:47   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 33/36] qemu-char: move pty_chr_update_read_handler around Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 34/36] qemu-char: make writes thread-safe Paolo Bonzini
2014-06-25  6:06   ` Stefan Weil
2014-06-25  7:03     ` Paolo Bonzini
2014-06-18  6:43 ` Paolo Bonzini [this message]
2014-06-18  6:44 ` [Qemu-devel] [PATCH 2.1 36/36] monitor: protect event emission Paolo Bonzini
     [not found] ` <1403073840-32603-32-git-send-email-pbonzini@redhat.com>
2014-06-19 12:03   ` [Qemu-devel] [PATCH 2.1 31/36] qemu-char: introduce qemu_chr_alloc Eric Blake
2014-06-19 12:52     ` Paolo Bonzini
2014-06-19 18:40 ` [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Luiz Capitulino
2014-06-20 15:44 ` Eric Blake
2014-06-20 23:34   ` Wenchao Xia
2014-06-26 15:50 ` Markus Armbruster
2014-06-26 15:56   ` Luiz Capitulino

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1403073840-32603-36-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=lcapitulino@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=wenchaoqemu@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.