diff options
author | Mark McLoughlin <markmc@redhat.com> | 2009-04-29 13:30:24 +0100 |
---|---|---|
committer | Mark McLoughlin <markmc@redhat.com> | 2009-06-09 11:38:50 +0100 |
commit | e19eb22486f258a421108ac22b8380a4e2f16b97 (patch) | |
tree | eb4eb3fc252294521c32d1de75769b4939568d67 /net.c | |
parent | f3b6c7fcf8fca857b3c3ba0aa5b3a06d7ce0ac37 (diff) |
net: make use of async packet sending API in tap client
If a packet is queued by qemu_send_packet(), remove I/O
handler for the tap fd until we get notification that the
packet has been sent.
A not insignificant side effect of this is we can now
drain the tap send queue in one go without fear of packets
being dropped.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Diffstat (limited to 'net.c')
-rw-r--r-- | net.c | 24 |
1 files changed, 20 insertions, 4 deletions
@@ -1079,15 +1079,31 @@ static ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen) } #endif +static void tap_send(void *opaque); + +static void tap_send_completed(VLANClientState *vc) +{ + TAPState *s = vc->opaque; + + qemu_set_fd_handler2(s->fd, tap_can_send, tap_send, NULL, s); +} + static void tap_send(void *opaque) { TAPState *s = opaque; int size; - size = tap_read_packet(s->fd, s->buf, sizeof(s->buf)); - if (size > 0) { - qemu_send_packet(s->vc, s->buf, size); - } + do { + size = tap_read_packet(s->fd, s->buf, sizeof(s->buf)); + if (size <= 0) { + break; + } + + size = qemu_send_packet_async(s->vc, s->buf, size, tap_send_completed); + if (size == 0) { + qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); + } + } while (size > 0); } static void tap_cleanup(VLANClientState *vc) |