From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>,
Paolo Bonzini <pbonzini@redhat.com>
Subject: [Qemu-devel] [PATCH v2 1/3] net: asynchronous send/receive infrastructure for net/socket.c
Date: Tue, 21 Aug 2012 16:52:29 +0100 [thread overview]
Message-ID: <1345564351-14693-2-git-send-email-stefanha@linux.vnet.ibm.com> (raw)
In-Reply-To: <1345564351-14693-1-git-send-email-stefanha@linux.vnet.ibm.com>
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 <stefanha@linux.vnet.ibm.com>
---
net/socket.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 52 insertions(+), 6 deletions(-)
diff --git a/net/socket.c b/net/socket.c
index c172c24..54e32f0 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 = {
--
1.7.10.4
next prev parent reply other threads:[~2012-08-21 15:52 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-21 15:52 [Qemu-devel] [PATCH v2 0/3] net: asynchronous send/receive for net/socket.c Stefan Hajnoczi
2012-08-21 15:52 ` Stefan Hajnoczi [this message]
2012-08-21 16:39 ` [Qemu-devel] [PATCH v2 1/3] net: asynchronous send/receive infrastructure " ronnie sahlberg
2012-08-21 18:54 ` [Qemu-devel] Ping 1.2 PATCH "eventfd: making it thread safe" (was Re: [PATCH v2 1/3] net: asynchronous send/receive infrastructure for net/socket.c) Paolo Bonzini
2012-08-21 19:06 ` Anthony Liguori
2012-08-22 21:07 ` Paolo Bonzini
2012-08-22 21:25 ` Anthony Liguori
2012-08-22 9:24 ` [Qemu-devel] [PATCH v2 1/3] net: asynchronous send/receive infrastructure for net/socket.c Stefan Hajnoczi
2012-08-21 15:52 ` [Qemu-devel] [PATCH v2 2/3] net: EAGAIN handling for net/socket.c UDP Stefan Hajnoczi
2012-08-21 15:52 ` [Qemu-devel] [PATCH v2 3/3] net: EAGAIN handling for net/socket.c TCP Stefan Hajnoczi
2012-08-29 15:35 ` [Qemu-devel] [PATCH v2 0/3] net: asynchronous send/receive for net/socket.c Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1345564351-14693-2-git-send-email-stefanha@linux.vnet.ibm.com \
--to=stefanha@linux.vnet.ibm.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).