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