aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chardev/char-socket.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 7ca5d97af3..03f03407b0 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -150,7 +150,7 @@ static void tcp_chr_accept(QIONetListener *listener,
void *opaque);
static int tcp_chr_read_poll(void *opaque);
-static void tcp_chr_disconnect(Chardev *chr);
+static void tcp_chr_disconnect_locked(Chardev *chr);
/* Called with chr_write_lock held. */
static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
@@ -174,7 +174,7 @@ static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
if (ret < 0 && errno != EAGAIN) {
if (tcp_chr_read_poll(chr) <= 0) {
- tcp_chr_disconnect(chr);
+ tcp_chr_disconnect_locked(chr);
return len;
} /* else let the read handler finish it properly */
}
@@ -469,8 +469,9 @@ static void update_disconnected_filename(SocketChardev *s)
/* NB may be called even if tcp_chr_connect has not been
* reached, due to TLS or telnet initialization failure,
* so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED
+ * This must be called with chr->chr_write_lock held.
*/
-static void tcp_chr_disconnect(Chardev *chr)
+static void tcp_chr_disconnect_locked(Chardev *chr)
{
SocketChardev *s = SOCKET_CHARDEV(chr);
bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED;
@@ -490,6 +491,13 @@ static void tcp_chr_disconnect(Chardev *chr)
}
}
+static void tcp_chr_disconnect(Chardev *chr)
+{
+ qemu_mutex_lock(&chr->chr_write_lock);
+ tcp_chr_disconnect_locked(chr);
+ qemu_mutex_unlock(&chr->chr_write_lock);
+}
+
static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
{
Chardev *chr = CHARDEV(opaque);
@@ -1131,8 +1139,10 @@ static gboolean socket_reconnect_timeout(gpointer opaque)
Chardev *chr = CHARDEV(opaque);
SocketChardev *s = SOCKET_CHARDEV(opaque);
+ qemu_mutex_lock(&chr->chr_write_lock);
g_source_unref(s->reconnect_timer);
s->reconnect_timer = NULL;
+ qemu_mutex_unlock(&chr->chr_write_lock);
if (chr->be_open) {
return false;