aboutsummaryrefslogtreecommitdiff
path: root/net.c
diff options
context:
space:
mode:
authorMark McLoughlin <markmc@redhat.com>2009-10-08 19:58:31 +0100
committerAnthony Liguori <aliguori@us.ibm.com>2009-10-15 09:32:03 -0500
commitf71058439974f6236ecc0a8eeb58ccc2e8fc87f9 (patch)
treedff36303bdf4f4c5f6bd4b69aceca2f81e0f939c /net.c
parent283c7c63f5c56c4d0340fb39093fb47e75cb122e (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.c138
1 files changed, 23 insertions, 115 deletions
diff --git a/net.c b/net.c
index 5d78f04e04..2c7b2ef1a7 100644
--- a/net.c
+++ b/net.c
@@ -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);