summary refs log tree commit diff stats
path: root/net/socket.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-06-12 15:39:05 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-06-12 15:39:05 +0100
commit0a2df857a7038c75379cc575de5d4be4c0ac629e (patch)
tree700646940e9fe7ea5db58e88289d4f333083d4ad /net/socket.c
parent9faffeb7772fddcb5d3fb2dbdcfe7e8a38f01637 (diff)
parentfafa4d508b42a70a59a6bd647a2c0cfad86246c3 (diff)
downloadfocaccia-qemu-0a2df857a7038c75379cc575de5d4be4c0ac629e.tar.gz
focaccia-qemu-0a2df857a7038c75379cc575de5d4be4c0ac629e.zip
Merge remote-tracking branch 'remotes/stefanha/tags/net-pull-request' into staging
# gpg: Signature made Fri Jun 12 13:57:20 2015 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/net-pull-request:
  qmp/hmp: add rocker device support
  rocker: bring link up/down on PHY enable/disable
  rocker: update tests using hw-derived interface names
  rocker: Add support for phys name
  iohandler: Change return type of qemu_set_fd_handler to "void"
  event-notifier: Always return 0 for posix implementation
  xen_backend: Remove unused error handling of qemu_set_fd_handler
  oss: Remove unused error handling of qemu_set_fd_handler
  alsaaudio: Remove unused error handling of qemu_set_fd_handler
  main-loop: Drop qemu_set_fd_handler2
  Change qemu_set_fd_handler2(..., NULL, ...) to qemu_set_fd_handler
  tap: Drop tap_can_send
  net/socket: Drop net_socket_can_send
  netmap: Drop netmap_can_send
  l2tpv3: Drop l2tpv3_can_send
  stubs: Add qemu_set_fd_handler

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/net/socket.c b/net/socket.c
index 5a19aa1881..c752696cbb 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -51,21 +51,12 @@ typedef struct 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);
+    qemu_set_fd_handler(s->fd,
+                        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)
@@ -142,6 +133,15 @@ static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf,
     return ret;
 }
 
+static void net_socket_send_completed(NetClientState *nc, ssize_t len)
+{
+    NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
+
+    if (!s->read_poll) {
+        net_socket_read_poll(s, true);
+    }
+}
+
 static void net_socket_send(void *opaque)
 {
     NetSocketState *s = opaque;
@@ -211,9 +211,13 @@ static void net_socket_send(void *opaque)
             buf += l;
             size -= l;
             if (s->index >= s->packet_len) {
-                qemu_send_packet(&s->nc, s->buf, s->packet_len);
                 s->index = 0;
                 s->state = 0;
+                if (qemu_send_packet_async(&s->nc, s->buf, size,
+                                           net_socket_send_completed) == 0) {
+                    net_socket_read_poll(s, false);
+                    break;
+                }
             }
             break;
         }
@@ -234,7 +238,10 @@ static void net_socket_send_dgram(void *opaque)
         net_socket_write_poll(s, false);
         return;
     }
-    qemu_send_packet(&s->nc, s->buf, size);
+    if (qemu_send_packet_async(&s->nc, s->buf, size,
+                               net_socket_send_completed) == 0) {
+        net_socket_read_poll(s, false);
+    }
 }
 
 static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr *localaddr)