From patchwork Fri Sep 14 08:46:58 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 183866 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 7C1772C0086 for ; Fri, 14 Sep 2012 20:12:15 +1000 (EST) Received: from localhost ([::1]:42591 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TCRZK-00064I-7D for incoming@patchwork.ozlabs.org; Fri, 14 Sep 2012 04:48:10 -0400 Received: from eggs.gnu.org ([208.118.235.92]:50278) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TCRYo-0004rl-Ja for qemu-devel@nongnu.org; Fri, 14 Sep 2012 04:47:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TCRYn-0000wC-5t for qemu-devel@nongnu.org; Fri, 14 Sep 2012 04:47:38 -0400 Received: from mail-wi0-f175.google.com ([209.85.212.175]:57077) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TCRYm-0000uG-V3 for qemu-devel@nongnu.org; Fri, 14 Sep 2012 04:47:37 -0400 Received: by mail-wi0-f175.google.com with SMTP id hm2so5783529wib.10 for ; Fri, 14 Sep 2012 01:47:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=/uxAauC7JGe6QtE9DiipLuFu+lOWYAam46m531Me+0k=; b=FSGXxPLgb+UzaP0ZBwtQcBmQk0sfrCZwaS1uabdCTiwiwv9NPlI1qQETkx0D6ARxNU kMJWd83xaCir6Nefgiu+Mdl1ejJUI/oUPG7ACqCJqBiAI10lPDBo0tlBrPeGc/jwFHhX b1FGSBcr8MchvOPv9MrlswJDpPt0583n19mSisKlU97likTxjvR5pvxqV5CSfOKCKq5B Rw95i5sHkBf17YwzF9OVF8TXrBNlTPPQtlbvPk5fWHBifKDPD+4i9Xc0aNskGpOTqy+3 V9Jc0TEjpNlKfWDf7HIbX+RgQjv4GGG38la8ygjsI6bjZ81H/PV0rXoImTJZcR1ug8ix kJUA== Received: by 10.180.104.197 with SMTP id gg5mr4437965wib.9.1347612456486; Fri, 14 Sep 2012 01:47:36 -0700 (PDT) Received: from localhost ([109.224.133.37]) by mx.google.com with ESMTPS id fb20sm2657934wid.1.2012.09.14.01.47.35 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 14 Sep 2012 01:47:35 -0700 (PDT) From: Stefan Hajnoczi To: Anthony Liguori Date: Fri, 14 Sep 2012 09:46:58 +0100 Message-Id: <1347612420-5704-12-git-send-email-stefanha@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1347612420-5704-1-git-send-email-stefanha@gmail.com> References: <1347612420-5704-1-git-send-email-stefanha@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.212.175 Cc: qemu-devel@nongnu.org, Stefan Hajnoczi Subject: [Qemu-devel] [PATCH 11/13] net: asynchronous send/receive infrastructure for net/socket.c 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: Stefan Hajnoczi The net/socket.c net client is not truly asynchronous. This patch borrows the qemu_set_fd_handler2() code from net/tap.c as the basis for proper asynchronous send/receive. Only read packets from the socket when the peer is able to receive. This avoids needless queuing. Later patches implement asynchronous send. Signed-off-by: Stefan Hajnoczi --- net/socket.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/net/socket.c b/net/socket.c index 7c602e4..7bff536 100644 --- a/net/socket.c +++ b/net/socket.c @@ -42,9 +42,51 @@ typedef struct NetSocketState { unsigned int packet_len; uint8_t buf[4096]; struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */ + IOHandler *send_fn; /* differs between SOCK_STREAM/SOCK_DGRAM */ + bool read_poll; /* waiting to receive data? */ + bool write_poll; /* waiting to transmit data? */ } NetSocketState; static void net_socket_accept(void *opaque); +static void net_socket_writable(void *opaque); + +/* Only read packets from socket when peer can receive them */ +static int net_socket_can_send(void *opaque) +{ + NetSocketState *s = opaque; + + return qemu_can_send_packet(&s->nc); +} + +static void net_socket_update_fd_handler(NetSocketState *s) +{ + qemu_set_fd_handler2(s->fd, + s->read_poll ? net_socket_can_send : NULL, + s->read_poll ? s->send_fn : NULL, + s->write_poll ? net_socket_writable : NULL, + s); +} + +static void net_socket_read_poll(NetSocketState *s, bool enable) +{ + s->read_poll = enable; + net_socket_update_fd_handler(s); +} + +static void net_socket_write_poll(NetSocketState *s, bool enable) +{ + s->write_poll = enable; + net_socket_update_fd_handler(s); +} + +static void net_socket_writable(void *opaque) +{ + NetSocketState *s = opaque; + + net_socket_write_poll(s, false); + + qemu_flush_queued_packets(&s->nc); +} /* XXX: we consider we can send the whole packet without blocking */ static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, size_t size) @@ -81,7 +123,8 @@ static void net_socket_send(void *opaque) } else if (size == 0) { /* end of connection */ eoc: - qemu_set_fd_handler(s->fd, NULL, NULL, NULL); + net_socket_read_poll(s, false); + net_socket_write_poll(s, false); if (s->listen_fd != -1) { qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s); } @@ -152,7 +195,8 @@ static void net_socket_send_dgram(void *opaque) return; if (size == 0) { /* end of connection */ - qemu_set_fd_handler(s->fd, NULL, NULL, NULL); + net_socket_read_poll(s, false); + net_socket_write_poll(s, false); return; } qemu_send_packet(&s->nc, s->buf, size); @@ -243,7 +287,8 @@ static void net_socket_cleanup(NetClientState *nc) { NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc); if (s->fd != -1) { - qemu_set_fd_handler(s->fd, NULL, NULL, NULL); + net_socket_read_poll(s, false); + net_socket_write_poll(s, false); close(s->fd); s->fd = -1; } @@ -314,8 +359,8 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer, s->fd = fd; s->listen_fd = -1; - - qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s); + s->send_fn = net_socket_send_dgram; + net_socket_read_poll(s, true); /* mcast: save bound address as dst */ if (is_connected) { @@ -332,7 +377,8 @@ err: static void net_socket_connect(void *opaque) { NetSocketState *s = opaque; - qemu_set_fd_handler(s->fd, net_socket_send, NULL, s); + s->send_fn = net_socket_send; + net_socket_read_poll(s, true); } static NetClientInfo net_socket_info = {