From 582cb89beb597247ceb6d82cdfc8fc983ffe8496 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 16 Jan 2013 19:29:27 +0100 Subject: Add a way to put things at the front of the queue for any throttle group. Adds a DoubleLocklessQueue and uses it for the outgoing buckets. Added a flag value to the Throttle Type (again) because although it's hacky, it's the best of a bad bunch to get the message through the UDP stack to where it's needed. --- .../Region/ClientStack/Linden/UDP/LLUDPClient.cs | 54 ++++++++++++++++++---- 1 file changed, 44 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index f1a1812..e52ac37 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -92,7 +92,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Packets we have sent that need to be ACKed by the client public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); /// ACKs that are queued up, waiting to be sent to the client - public readonly OpenSim.Framework.LocklessQueue PendingAcks = new OpenSim.Framework.LocklessQueue(); + public readonly DoubleLocklessQueue PendingAcks = new DoubleLocklessQueue(); /// Current packet sequence number public int CurrentSequence; @@ -146,7 +146,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Throttle buckets for each packet category private readonly TokenBucket[] m_throttleCategories; /// Outgoing queues for throttled packets - private readonly OpenSim.Framework.LocklessQueue[] m_packetOutboxes = new OpenSim.Framework.LocklessQueue[THROTTLE_CATEGORY_COUNT]; + private readonly DoubleLocklessQueue[] m_packetOutboxes = new DoubleLocklessQueue[THROTTLE_CATEGORY_COUNT]; /// A container that can hold one packet for each outbox, used to store /// dequeued packets that are being held for throttling private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; @@ -202,7 +202,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ThrottleOutPacketType type = (ThrottleOutPacketType)i; // Initialize the packet outboxes, where packets sit while they are waiting for tokens - m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue(); + m_packetOutboxes[i] = new DoubleLocklessQueue(); // Initialize the token buckets that control the throttling for each category m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type)); } @@ -430,15 +430,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue) { + return EnqueueOutgoing(packet, forceQueue, false); + } + + public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue, bool highPriority) + { int category = (int)packet.Category; if (category >= 0 && category < m_packetOutboxes.Length) { - OpenSim.Framework.LocklessQueue queue = m_packetOutboxes[category]; + DoubleLocklessQueue queue = m_packetOutboxes[category]; if (m_deliverPackets == false) { - queue.Enqueue(packet); + queue.Enqueue(packet, highPriority); return true; } @@ -449,7 +454,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // queued packets if (queue.Count > 0) { - queue.Enqueue(packet); + queue.Enqueue(packet, highPriority); return true; } @@ -462,7 +467,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP else { // Force queue specified or not enough tokens in the bucket, queue this packet - queue.Enqueue(packet); + queue.Enqueue(packet, highPriority); return true; } } @@ -494,7 +499,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (m_deliverPackets == false) return false; OutgoingPacket packet = null; - OpenSim.Framework.LocklessQueue queue; + DoubleLocklessQueue queue; TokenBucket bucket; bool packetSent = false; ThrottleOutPacketTypeFlags emptyCategories = 0; @@ -534,7 +539,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } catch { - m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue(); + m_packetOutboxes[i] = new DoubleLocklessQueue(); } if (success) { @@ -567,7 +572,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue(); + m_packetOutboxes[i] = new DoubleLocklessQueue(); emptyCategories |= CategoryToFlag(i); } } @@ -724,4 +729,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } } + + public class DoubleLocklessQueue : OpenSim.Framework.LocklessQueue + { + OpenSim.Framework.LocklessQueue highQueue = new OpenSim.Framework.LocklessQueue(); + + public override int Count + { + get + { + return base.Count + highQueue.Count; + } + } + + public override bool Dequeue(out T item) + { + if (highQueue.Dequeue(out item)) + return true; + + return base.Dequeue(out item); + } + + public void Enqueue(T item, bool highPriority) + { + if (highPriority) + highQueue.Enqueue(item); + else + Enqueue(item); + } + } } -- cgit v1.1