diff options
author | Mark McLoughlin <markmc@redhat.com> | 2009-10-08 19:58:31 +0100 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-10-15 09:32:03 -0500 |
commit | f71058439974f6236ecc0a8eeb58ccc2e8fc87f9 (patch) | |
tree | dff36303bdf4f4c5f6bd4b69aceca2f81e0f939c /net.c | |
parent | 283c7c63f5c56c4d0340fb39093fb47e75cb122e (diff) |
net: refactor packet queueing code
The packet queue code is fairly standalone, has some complex details and
easily reusable. It makes sense to split it out on its own. This patch
doesn't contain any functional changes.
Patchworks-ID: 35511
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'net.c')
-rw-r--r-- | net.c | 138 |
1 files changed, 23 insertions, 115 deletions
@@ -422,15 +422,16 @@ int qemu_can_send_packet(VLANClientState *sender) return 0; } -static int -qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size) +static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender, + const uint8_t *buf, + size_t size, + void *opaque) { + VLANState *vlan = opaque; VLANClientState *vc; int ret = -1; - sender->vlan->delivering = 1; - - QTAILQ_FOREACH(vc, &sender->vlan->clients, next) { + QTAILQ_FOREACH(vc, &vlan->clients, next) { ssize_t len; if (vc == sender) { @@ -447,24 +448,15 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size) ret = (ret >= 0) ? ret : len; } - sender->vlan->delivering = 0; - return ret; } void qemu_purge_queued_packets(VLANClientState *vc) { - VLANPacket *packet, *next; - if (!vc->vlan) return; - QTAILQ_FOREACH_SAFE(packet, &vc->vlan->send_queue, entry, next) { - if (packet->sender == vc) { - QTAILQ_REMOVE(&vc->vlan->send_queue, packet, entry); - qemu_free(packet); - } - } + qemu_net_queue_purge(vc->vlan->send_queue, vc); } void qemu_flush_queued_packets(VLANClientState *vc) @@ -472,47 +464,13 @@ void qemu_flush_queued_packets(VLANClientState *vc) if (!vc->vlan) return; - while (!QTAILQ_EMPTY(&vc->vlan->send_queue)) { - VLANPacket *packet; - int ret; - - packet = QTAILQ_FIRST(&vc->vlan->send_queue); - QTAILQ_REMOVE(&vc->vlan->send_queue, packet, entry); - - ret = qemu_deliver_packet(packet->sender, packet->data, packet->size); - if (ret == 0 && packet->sent_cb != NULL) { - QTAILQ_INSERT_HEAD(&vc->vlan->send_queue, packet, entry); - break; - } - - if (packet->sent_cb) - packet->sent_cb(packet->sender, ret); - - qemu_free(packet); - } -} - -static void qemu_enqueue_packet(VLANClientState *sender, - const uint8_t *buf, int size, - NetPacketSent *sent_cb) -{ - VLANPacket *packet; - - packet = qemu_malloc(sizeof(VLANPacket) + size); - packet->sender = sender; - packet->size = size; - packet->sent_cb = sent_cb; - memcpy(packet->data, buf, size); - - QTAILQ_INSERT_TAIL(&sender->vlan->send_queue, packet, entry); + qemu_net_queue_flush(vc->vlan->send_queue); } ssize_t qemu_send_packet_async(VLANClientState *sender, const uint8_t *buf, int size, NetPacketSent *sent_cb) { - int ret; - if (sender->link_down || !sender->vlan) { return size; } @@ -522,20 +480,8 @@ ssize_t qemu_send_packet_async(VLANClientState *sender, hex_dump(stdout, buf, size); #endif - if (sender->vlan->delivering) { - qemu_enqueue_packet(sender, buf, size, NULL); - return size; - } - - ret = qemu_deliver_packet(sender, buf, size); - if (ret == 0 && sent_cb != NULL) { - qemu_enqueue_packet(sender, buf, size, sent_cb); - return 0; - } - - qemu_flush_queued_packets(sender); - - return ret; + return qemu_net_queue_send(sender->vlan->send_queue, + sender, buf, size, sent_cb); } void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size) @@ -571,15 +517,16 @@ static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt) return offset; } -static int qemu_deliver_packet_iov(VLANClientState *sender, - const struct iovec *iov, int iovcnt) +static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender, + const struct iovec *iov, + int iovcnt, + void *opaque) { + VLANState *vlan = opaque; VLANClientState *vc; - int ret = -1; - - sender->vlan->delivering = 1; + ssize_t ret = -1; - QTAILQ_FOREACH(vc, &sender->vlan->clients, next) { + QTAILQ_FOREACH(vc, &vlan->clients, next) { ssize_t len; if (vc == sender) { @@ -600,61 +547,19 @@ static int qemu_deliver_packet_iov(VLANClientState *sender, ret = (ret >= 0) ? ret : len; } - sender->vlan->delivering = 0; - return ret; } -static ssize_t qemu_enqueue_packet_iov(VLANClientState *sender, - const struct iovec *iov, int iovcnt, - NetPacketSent *sent_cb) -{ - VLANPacket *packet; - size_t max_len = 0; - int i; - - max_len = calc_iov_length(iov, iovcnt); - - packet = qemu_malloc(sizeof(VLANPacket) + max_len); - packet->sender = sender; - packet->sent_cb = sent_cb; - packet->size = 0; - - for (i = 0; i < iovcnt; i++) { - size_t len = iov[i].iov_len; - - memcpy(packet->data + packet->size, iov[i].iov_base, len); - packet->size += len; - } - - QTAILQ_INSERT_TAIL(&sender->vlan->send_queue, packet, entry); - - return packet->size; -} - ssize_t qemu_sendv_packet_async(VLANClientState *sender, const struct iovec *iov, int iovcnt, NetPacketSent *sent_cb) { - int ret; - if (sender->link_down || !sender->vlan) { return calc_iov_length(iov, iovcnt); } - if (sender->vlan->delivering) { - return qemu_enqueue_packet_iov(sender, iov, iovcnt, NULL); - } - - ret = qemu_deliver_packet_iov(sender, iov, iovcnt); - if (ret == 0 && sent_cb != NULL) { - qemu_enqueue_packet_iov(sender, iov, iovcnt, sent_cb); - return 0; - } - - qemu_flush_queued_packets(sender); - - return ret; + return qemu_net_queue_send_iov(sender->vlan->send_queue, + sender, iov, iovcnt, sent_cb); } ssize_t @@ -2348,7 +2253,10 @@ VLANState *qemu_find_vlan(int id, int allocate) vlan = qemu_mallocz(sizeof(VLANState)); vlan->id = id; QTAILQ_INIT(&vlan->clients); - QTAILQ_INIT(&vlan->send_queue); + + vlan->send_queue = qemu_new_net_queue(qemu_vlan_deliver_packet, + qemu_vlan_deliver_packet_iov, + vlan); QTAILQ_INSERT_TAIL(&vlans, vlan, next); |