[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 08/14] chardev: allow telnet gsource to switch gcont
From: |
Peter Xu |
Subject: |
[Qemu-devel] [PATCH 08/14] chardev: allow telnet gsource to switch gcontext |
Date: |
Wed, 28 Feb 2018 13:06:27 +0800 |
It was originally created by qio_channel_add_watch() so it's always
assigning the task to main context. Now we use the new API called
qio_channel_add_watch_full() so that we get the GSource handle rather
than the tag ID.
Meanwhile, caching the gsource in SocketChardev.telnet_source so that we
can also do dynamic context switch when update read handlers.
Signed-off-by: Peter Xu <address@hidden>
---
chardev/char-socket.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 8f0935cd15..a16d894c40 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -59,6 +59,7 @@ typedef struct {
bool is_listen;
bool is_telnet;
bool is_tn3270;
+ GSource *telnet_source;
GSource *reconnect_timer;
int64_t reconnect_time;
@@ -69,6 +70,7 @@ typedef struct {
OBJECT_CHECK(SocketChardev, (obj), TYPE_CHARDEV_SOCKET)
static gboolean socket_reconnect_timeout(gpointer opaque);
+static void tcp_chr_telnet_init(Chardev *chr);
static void tcp_chr_reconn_timer_cancel(SocketChardev *s)
{
@@ -555,6 +557,15 @@ static void tcp_chr_connect(void *opaque)
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}
+static void tcp_chr_telnet_destroy(SocketChardev *s)
+{
+ if (s->telnet_source) {
+ g_source_destroy(s->telnet_source);
+ g_source_unref(s->telnet_source);
+ s->telnet_source = NULL;
+ }
+}
+
static void tcp_chr_update_read_handler(Chardev *chr)
{
SocketChardev *s = SOCKET_CHARDEV(chr);
@@ -568,6 +579,11 @@ static void tcp_chr_update_read_handler(Chardev *chr)
qio_net_listener_set_context(s->listener, chr->gcontext);
}
+ if (s->telnet_source) {
+ tcp_chr_telnet_destroy(s);
+ tcp_chr_telnet_init(CHARDEV(s));
+ }
+
if (!s->connected) {
return;
}
@@ -592,6 +608,7 @@ static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
gpointer user_data)
{
TCPChardevTelnetInit *init = user_data;
+ SocketChardev *s = SOCKET_CHARDEV(init->chr);
ssize_t ret;
ret = qio_channel_write(ioc, init->buf, init->buflen, NULL);
@@ -616,6 +633,8 @@ static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
end:
g_free(init);
+ g_source_unref(s->telnet_source);
+ s->telnet_source = NULL;
return G_SOURCE_REMOVE;
}
@@ -655,10 +674,10 @@ static void tcp_chr_telnet_init(Chardev *chr)
#undef IACSET
- qio_channel_add_watch(
- s->ioc, G_IO_OUT,
- tcp_chr_telnet_init_io,
- init, NULL);
+ s->telnet_source = qio_channel_add_watch_full(s->ioc, G_IO_OUT,
+ tcp_chr_telnet_init_io,
+ init, NULL,
+ chr->gcontext);
}
@@ -831,6 +850,7 @@ static void char_socket_finalize(Object *obj)
tcp_chr_free_connection(chr);
tcp_chr_reconn_timer_cancel(s);
qapi_free_SocketAddress(s->addr);
+ tcp_chr_telnet_destroy(s);
if (s->listener) {
qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
object_unref(OBJECT(s->listener));
--
2.14.3
- Re: [Qemu-devel] [PATCH 03/14] qio: introduce qio_channel_add_watch_full(), (continued)
[Qemu-devel] [PATCH 04/14] migration: let incoming side use thread context, Peter Xu, 2018/02/28
[Qemu-devel] [PATCH 05/14] qio: refactor net listener source operations, Peter Xu, 2018/02/28
[Qemu-devel] [PATCH 06/14] qio: store gsources for net listeners, Peter Xu, 2018/02/28
[Qemu-devel] [PATCH 07/14] qio/chardev: update net listener gcontext, Peter Xu, 2018/02/28
[Qemu-devel] [PATCH 08/14] chardev: allow telnet gsource to switch gcontext,
Peter Xu <=
[Qemu-devel] [PATCH 09/14] qio: basic non-default context support for thread, Peter Xu, 2018/02/28
[Qemu-devel] [PATCH 10/14] qio: refcount QIOTask, Peter Xu, 2018/02/28
[Qemu-devel] [PATCH 11/14] qio/chardev: return QIOTask when connect async, Peter Xu, 2018/02/28
[Qemu-devel] [PATCH 12/14] qio: move QIOTaskThreadData into QIOTask, Peter Xu, 2018/02/28