<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">From 3cb731b4477cf7c0df86af39b20291638f7a2e28 Mon Sep 17 00:00:00 2001
Message-Id: &lt;3cb731b4477cf7c0df86af39b20291638f7a2e28.1368111914.git.minovotn@redhat.com&gt;
In-Reply-To: &lt;405603258af5154387bea676be1f904b6713f6ae.1368111913.git.minovotn@redhat.com&gt;
References: &lt;405603258af5154387bea676be1f904b6713f6ae.1368111913.git.minovotn@redhat.com&gt;
From: Amit Shah &lt;amit.shah@redhat.com&gt;
Date: Wed, 24 Apr 2013 08:18:11 +0200
Subject: [PATCH 37/65] qemu-char: tcp: make use GIOChannel

RH-Author: Amit Shah &lt;amit.shah@redhat.com&gt;
Message-id: &lt;b5d7a7f5adf9cc3df7fdc2f644d70cf0202e66c9.1366724981.git.amit.shah@redhat.com&gt;
Patchwork-id: 50815
O-Subject: [RHEL6.5 qemu-kvm PATCH 37/65] qemu-char: tcp: make use GIOChannel
Bugzilla: 909059
RH-Acked-by: Hans de Goede &lt;hdegoede@redhat.com&gt;
RH-Acked-by: Gerd Hoffmann &lt;kraxel@redhat.com&gt;
RH-Acked-by: Paolo Bonzini &lt;pbonzini@redhat.com&gt;

From: Anthony Liguori &lt;aliguori@us.ibm.com&gt;

I didn't bother switching to g_io_channel_read/write because we need to use
sendmsg on Unix.  No problem though since we're using an unbuffered channel.

Signed-off-by: Anthony Liguori &lt;aliguori@us.ibm.com&gt;
Signed-off-by: Amit Shah &lt;amit.shah@redhat.com&gt;
Message-id: 002f726576dfb51bca4854aa257b74d77c1cd4e8.1362505276.git.amit.shah@redhat.com
Signed-off-by: Anthony Liguori &lt;aliguori@us.ibm.com&gt;
(cherry picked from commit 2ea5a7af7bfa576a5936400ccca4144caca9640b)

Signed-off-by: Amit Shah &lt;amit.shah@redhat.com&gt;

Conflicts:
	qemu-char.c

    * We don't have tcp_chr_add_client()
    * We don't have qemu_chr_open_socket_fd()
---
 qemu-char.c | 64 +++++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 45 insertions(+), 19 deletions(-)

Signed-off-by: Michal Novotny &lt;minovotn@redhat.com&gt;
---
 qemu-char.c | 64 +++++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 45 insertions(+), 19 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index deba461..9839084 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2061,6 +2061,9 @@ return_err:
 /* TCP Net console */
 
 typedef struct {
+
+    GIOChannel *chan, *listen_chan;
+    guint tag, listen_tag;
     int fd, listen_fd;
     int connected;
     int max_size;
@@ -2070,13 +2073,13 @@ typedef struct {
     int msgfd;
 } TCPCharDriver;
 
-static void tcp_chr_accept(void *opaque);
+static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque);
 
 static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
 {
     TCPCharDriver *s = chr-&gt;opaque;
     if (s-&gt;connected) {
-        return send_all(s-&gt;fd, buf, len);
+        return io_channel_send_all(s-&gt;chan, buf, len);
     } else {
         /* XXX: indicate an error ? */
         return len;
@@ -2208,15 +2211,16 @@ static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
 }
 #endif
 
-static void tcp_chr_read(void *opaque)
+static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
 {
     CharDriverState *chr = opaque;
     TCPCharDriver *s = chr-&gt;opaque;
     uint8_t buf[READ_BUF_LEN];
     int len, size;
 
-    if (!s-&gt;connected || s-&gt;max_size &lt;= 0)
-        return;
+    if (!s-&gt;connected || s-&gt;max_size &lt;= 0) {
+        return FALSE;
+    }
     len = sizeof(buf);
     if (len &gt; s-&gt;max_size)
         len = s-&gt;max_size;
@@ -2224,10 +2228,13 @@ static void tcp_chr_read(void *opaque)
     if (size == 0) {
         /* connection closed */
         s-&gt;connected = 0;
-        if (s-&gt;listen_fd &gt;= 0) {
-            qemu_set_fd_handler(s-&gt;listen_fd, tcp_chr_accept, NULL, chr);
+        if (s-&gt;listen_chan) {
+            s-&gt;listen_tag = g_io_add_watch(s-&gt;listen_chan, G_IO_IN, tcp_chr_accept, chr);
         }
-        qemu_set_fd_handler(s-&gt;fd, NULL, NULL, NULL);
+        g_source_remove(s-&gt;tag);
+        s-&gt;tag = 0;
+        g_io_channel_unref(s-&gt;chan);
+        s-&gt;chan = NULL;
         closesocket(s-&gt;fd);
         s-&gt;fd = -1;
         qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
@@ -2237,6 +2244,8 @@ static void tcp_chr_read(void *opaque)
         if (size &gt; 0)
             qemu_chr_be_write(chr, buf, size);
     }
+
+    return TRUE;
 }
 
 static void tcp_chr_connect(void *opaque)
@@ -2245,8 +2254,9 @@ static void tcp_chr_connect(void *opaque)
     TCPCharDriver *s = chr-&gt;opaque;
 
     s-&gt;connected = 1;
-    qemu_set_fd_handler2(s-&gt;fd, tcp_chr_read_poll,
-                         tcp_chr_read, NULL, chr);
+    if (s-&gt;chan) {
+        s-&gt;tag = io_add_watch_poll(s-&gt;chan, tcp_chr_read_poll, tcp_chr_read, chr);
+    }
     qemu_chr_generic_open(chr);
 }
 
@@ -2271,7 +2281,7 @@ static void socket_set_nodelay(int fd)
     setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&amp;val, sizeof(val));
 }
 
-static void tcp_chr_accept(void *opaque)
+static gboolean tcp_chr_accept(GIOChannel *channel, GIOCondition cond, void *opaque)
 {
     CharDriverState *chr = opaque;
     TCPCharDriver *s = chr-&gt;opaque;
@@ -2296,7 +2306,7 @@ static void tcp_chr_accept(void *opaque)
 	}
         fd = qemu_accept(s-&gt;listen_fd, addr, &amp;len);
         if (fd &lt; 0 &amp;&amp; errno != EINTR) {
-            return;
+            return FALSE;
         } else if (fd &gt;= 0) {
             if (s-&gt;do_telnetopt)
                 tcp_chr_telnet_init(fd);
@@ -2307,19 +2317,33 @@ static void tcp_chr_accept(void *opaque)
     if (s-&gt;do_nodelay)
         socket_set_nodelay(fd);
     s-&gt;fd = fd;
-    qemu_set_fd_handler(s-&gt;listen_fd, NULL, NULL, NULL);
+    s-&gt;chan = io_channel_from_socket(fd);
+    g_source_remove(s-&gt;listen_tag);
+    s-&gt;listen_tag = 0;
     tcp_chr_connect(chr);
+
+    return TRUE;
 }
 
 static void tcp_chr_close(CharDriverState *chr)
 {
     TCPCharDriver *s = chr-&gt;opaque;
     if (s-&gt;fd &gt;= 0) {
-        qemu_set_fd_handler(s-&gt;fd, NULL, NULL, NULL);
+        if (s-&gt;tag) {
+            g_source_remove(s-&gt;tag);
+        }
+        if (s-&gt;chan) {
+            g_io_channel_unref(s-&gt;chan);
+        }
         closesocket(s-&gt;fd);
     }
     if (s-&gt;listen_fd &gt;= 0) {
-        qemu_set_fd_handler(s-&gt;listen_fd, NULL, NULL, NULL);
+        if (s-&gt;listen_tag) {
+            g_source_remove(s-&gt;listen_tag);
+        }
+        if (s-&gt;listen_chan) {
+            g_io_channel_unref(s-&gt;listen_chan);
+        }
         closesocket(s-&gt;listen_fd);
     }
     qemu_free(s);
@@ -2381,14 +2405,16 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
 
     if (is_listen) {
         s-&gt;listen_fd = fd;
-        qemu_set_fd_handler(s-&gt;listen_fd, tcp_chr_accept, NULL, chr);
-        if (is_telnet)
+        s-&gt;listen_chan = io_channel_from_socket(s-&gt;listen_fd);
+        s-&gt;listen_tag = g_io_add_watch(s-&gt;listen_chan, G_IO_IN, tcp_chr_accept, chr);
+        if (is_telnet) {
             s-&gt;do_telnetopt = 1;
-
+        }
     } else {
         s-&gt;connected = 1;
         s-&gt;fd = fd;
         socket_set_nodelay(fd);
+        s-&gt;chan = io_channel_from_socket(s-&gt;fd);
         tcp_chr_connect(chr);
     }
 
@@ -2411,7 +2437,7 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
     if (is_listen &amp;&amp; is_waitconnect) {
         printf("QEMU waiting for connection on: %s\n",
                chr-&gt;filename);
-        tcp_chr_accept(chr);
+        tcp_chr_accept(s-&gt;listen_chan, G_IO_IN, chr);
         socket_set_nonblock(s-&gt;listen_fd);
     }
     return chr;
-- 
1.7.11.7

</pre></body></html>