From patchwork Tue Mar 5 17:51:22 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Shah X-Patchwork-Id: 225121 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 656792C0328 for ; Wed, 6 Mar 2013 04:54:43 +1100 (EST) Received: from localhost ([::1]:45092 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UCw4X-0005A8-Le for incoming@patchwork.ozlabs.org; Tue, 05 Mar 2013 12:54:41 -0500 Received: from eggs.gnu.org ([208.118.235.92]:44456) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UCw3z-00052k-9H for qemu-devel@nongnu.org; Tue, 05 Mar 2013 12:54:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UCw3x-0007oh-QM for qemu-devel@nongnu.org; Tue, 05 Mar 2013 12:54:07 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46667) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UCw3x-0007oc-Iy for qemu-devel@nongnu.org; Tue, 05 Mar 2013 12:54:05 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r25Hs3Kn012220 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 5 Mar 2013 12:54:03 -0500 Received: from localhost (ovpn-113-84.phx2.redhat.com [10.3.113.84]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r25HrnvR007221; Tue, 5 Mar 2013 12:53:50 -0500 From: Amit Shah To: qemu list Date: Tue, 5 Mar 2013 23:21:22 +0530 Message-Id: <002f726576dfb51bca4854aa257b74d77c1cd4e8.1362505276.git.amit.shah@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Amit Shah , Anthony Liguori , Anthony Liguori Subject: [Qemu-devel] [PATCH 07/20] qemu-char: tcp: make use GIOChannel X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Anthony Liguori 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 Signed-off-by: Amit Shah --- qemu-char.c | 60 ++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 94ff332..5a53491 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2285,6 +2285,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; @@ -2294,13 +2297,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->opaque; if (s->connected) { - return send_all(s->fd, buf, len); + return io_channel_send_all(s->chan, buf, len); } else { /* XXX: indicate an error ? */ return len; @@ -2440,15 +2443,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->opaque; uint8_t buf[READ_BUF_LEN]; int len, size; - if (!s->connected || s->max_size <= 0) - return; + if (!s->connected || s->max_size <= 0) { + return FALSE; + } len = sizeof(buf); if (len > s->max_size) len = s->max_size; @@ -2456,10 +2460,13 @@ static void tcp_chr_read(void *opaque) if (size == 0) { /* connection closed */ s->connected = 0; - if (s->listen_fd >= 0) { - qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr); + if (s->listen_chan) { + s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, tcp_chr_accept, chr); } - qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); + g_source_remove(s->tag); + s->tag = 0; + g_io_channel_unref(s->chan); + s->chan = NULL; closesocket(s->fd); s->fd = -1; qemu_chr_be_event(chr, CHR_EVENT_CLOSED); @@ -2469,6 +2476,8 @@ static void tcp_chr_read(void *opaque) if (size > 0) qemu_chr_be_write(chr, buf, size); } + + return TRUE; } #ifndef _WIN32 @@ -2484,9 +2493,8 @@ static void tcp_chr_connect(void *opaque) TCPCharDriver *s = chr->opaque; s->connected = 1; - if (s->fd >= 0) { - qemu_set_fd_handler2(s->fd, tcp_chr_read_poll, - tcp_chr_read, NULL, chr); + if (s->chan) { + s->tag = io_add_watch_poll(s->chan, tcp_chr_read_poll, tcp_chr_read, chr); } qemu_chr_generic_open(chr); } @@ -2516,13 +2524,15 @@ static int tcp_chr_add_client(CharDriverState *chr, int fd) if (s->do_nodelay) socket_set_nodelay(fd); s->fd = fd; - qemu_set_fd_handler2(s->listen_fd, NULL, NULL, NULL, NULL); + s->chan = io_channel_from_socket(fd); + g_source_remove(s->listen_tag); + s->listen_tag = 0; tcp_chr_connect(chr); return 0; } -static void tcp_chr_accept(void *opaque) +static gboolean tcp_chr_accept(GIOChannel *channel, GIOCondition cond, void *opaque) { CharDriverState *chr = opaque; TCPCharDriver *s = chr->opaque; @@ -2547,7 +2557,7 @@ static void tcp_chr_accept(void *opaque) } fd = qemu_accept(s->listen_fd, addr, &len); if (fd < 0 && errno != EINTR) { - return; + return FALSE; } else if (fd >= 0) { if (s->do_telnetopt) tcp_chr_telnet_init(fd); @@ -2556,17 +2566,29 @@ static void tcp_chr_accept(void *opaque) } if (tcp_chr_add_client(chr, fd) < 0) close(fd); + + return TRUE; } static void tcp_chr_close(CharDriverState *chr) { TCPCharDriver *s = chr->opaque; if (s->fd >= 0) { - qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); + if (s->tag) { + g_source_remove(s->tag); + } + if (s->chan) { + g_io_channel_unref(s->chan); + } closesocket(s->fd); } if (s->listen_fd >= 0) { - qemu_set_fd_handler2(s->listen_fd, NULL, NULL, NULL, NULL); + if (s->listen_tag) { + g_source_remove(s->listen_tag); + } + if (s->listen_chan) { + g_io_channel_unref(s->listen_chan); + } closesocket(s->listen_fd); } g_free(s); @@ -2632,7 +2654,8 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay, if (is_listen) { s->listen_fd = fd; - qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr); + s->listen_chan = io_channel_from_socket(s->listen_fd); + s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, tcp_chr_accept, chr); if (is_telnet) { s->do_telnetopt = 1; } @@ -2640,13 +2663,14 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay, s->connected = 1; s->fd = fd; socket_set_nodelay(fd); + s->chan = io_channel_from_socket(s->fd); tcp_chr_connect(chr); } if (is_listen && is_waitconnect) { printf("QEMU waiting for connection on: %s\n", chr->filename); - tcp_chr_accept(chr); + tcp_chr_accept(s->listen_chan, G_IO_IN, chr); socket_set_nonblock(s->listen_fd); } return chr;