diff options
Diffstat (limited to 'chardev')
| -rw-r--r-- | chardev/char-pty.c | 38 | ||||
| -rw-r--r-- | chardev/char-socket.c | 22 |
2 files changed, 43 insertions, 17 deletions
diff --git a/chardev/char-pty.c b/chardev/char-pty.c index 89315e6807..68fd4e20c3 100644 --- a/chardev/char-pty.c +++ b/chardev/char-pty.c @@ -51,15 +51,32 @@ typedef struct { static void pty_chr_update_read_handler_locked(Chardev *chr); static void pty_chr_state(Chardev *chr, int connected); +static void pty_chr_timer_cancel(PtyChardev *s) +{ + if (s->timer_src) { + g_source_destroy(s->timer_src); + g_source_unref(s->timer_src); + s->timer_src = NULL; + } +} + +static void pty_chr_open_src_cancel(PtyChardev *s) +{ + if (s->open_source) { + g_source_destroy(s->open_source); + g_source_unref(s->open_source); + s->open_source = NULL; + } +} + static gboolean pty_chr_timer(gpointer opaque) { struct Chardev *chr = CHARDEV(opaque); PtyChardev *s = PTY_CHARDEV(opaque); qemu_mutex_lock(&chr->chr_write_lock); - s->timer_src = NULL; - g_source_unref(s->open_source); - s->open_source = NULL; + pty_chr_timer_cancel(s); + pty_chr_open_src_cancel(s); if (!s->connected) { /* Next poll ... */ pty_chr_update_read_handler_locked(chr); @@ -68,15 +85,6 @@ static gboolean pty_chr_timer(gpointer opaque) return FALSE; } -static void pty_chr_timer_cancel(PtyChardev *s) -{ - if (s->timer_src) { - g_source_destroy(s->timer_src); - g_source_unref(s->timer_src); - s->timer_src = NULL; - } -} - /* Called with chr_write_lock held. */ static void pty_chr_rearm_timer(Chardev *chr, int ms) { @@ -195,11 +203,7 @@ static void pty_chr_state(Chardev *chr, int connected) PtyChardev *s = PTY_CHARDEV(chr); if (!connected) { - if (s->open_source) { - g_source_destroy(s->open_source); - g_source_unref(s->open_source); - s->open_source = NULL; - } + pty_chr_open_src_cancel(s); remove_fd_in_watch(chr); s->connected = 0; /* (re-)connect poll interval for idle guests: once per second. diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 77cdf487eb..a340af6cd3 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -42,6 +42,7 @@ typedef struct { QIOChannel *ioc; /* Client I/O channel */ QIOChannelSocket *sioc; /* Client master channel */ QIONetListener *listener; + GSource *hup_source; QCryptoTLSCreds *tls_creds; int connected; int max_size; @@ -352,6 +353,12 @@ static void tcp_chr_free_connection(Chardev *chr) s->read_msgfds_num = 0; } + if (s->hup_source != NULL) { + g_source_destroy(s->hup_source); + g_source_unref(s->hup_source); + s->hup_source = NULL; + } + tcp_set_msgfds(chr, NULL, 0); remove_fd_in_watch(chr); object_unref(OBJECT(s->sioc)); @@ -455,6 +462,15 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) return TRUE; } +static gboolean tcp_chr_hup(QIOChannel *channel, + GIOCondition cond, + void *opaque) +{ + Chardev *chr = CHARDEV(opaque); + tcp_chr_disconnect(chr); + return G_SOURCE_REMOVE; +} + static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len) { SocketChardev *s = SOCKET_CHARDEV(chr); @@ -528,6 +544,12 @@ static void tcp_chr_connect(void *opaque) tcp_chr_read, chr, chr->gcontext); } + + s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP); + g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup, + chr, NULL); + g_source_attach(s->hup_source, chr->gcontext); + qemu_chr_be_event(chr, CHR_EVENT_OPENED); } |