From 378a79e7cc6be3191dea41b617c05febd7ee5cbe Mon Sep 17 00:00:00 2001
From: Melanie
Date: Tue, 28 Aug 2012 22:17:17 +0200
Subject: Add a queue with two priority levels. This is a drop in replacement
for the BlockingQueue from OMV, but allows two priorities.
---
.../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 113 ++++++++++++++++++++-
1 file changed, 111 insertions(+), 2 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 7042c9a..f9ba14c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -110,7 +110,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Handlers for incoming packets
//PacketEventDictionary packetEvents = new PacketEventDictionary();
/// Incoming packets that are awaiting handling
- private OpenMetaverse.BlockingQueue packetInbox = new OpenMetaverse.BlockingQueue();
+ //private OpenMetaverse.BlockingQueue packetInbox = new OpenMetaverse.BlockingQueue();
+
+ private DoubleQueue packetInbox = new DoubleQueue();
+
///
//private UDPClientCollection m_clients = new UDPClientCollection();
/// Bandwidth throttle for this UDP server
@@ -919,7 +922,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion Ping Check Handling
// Inbox insertion
- packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet));
+ if (packet.Type == PacketType.AgentUpdate ||
+ packet.Type == PacketType.ChatFromViewer)
+ packetInbox.EnqueueHigh(new IncomingPacket((LLClientView)client, packet));
+ else
+ packetInbox.EnqueueLow(new IncomingPacket((LLClientView)client, packet));
}
#region BinaryStats
@@ -1519,4 +1526,106 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
}
+
+ internal class DoubleQueue where T:class
+ {
+ private Queue m_lowQueue = new Queue();
+ private Queue m_highQueue = new Queue();
+
+ private object m_syncRoot = new object();
+ private Semaphore m_s = new Semaphore(0, 1);
+
+ public DoubleQueue()
+ {
+ }
+
+ public virtual int Count
+ {
+ get { return m_highQueue.Count + m_lowQueue.Count; }
+ }
+
+ public virtual void Enqueue(T data)
+ {
+ Enqueue(m_lowQueue, data);
+ }
+
+ public virtual void EnqueueLow(T data)
+ {
+ Enqueue(m_lowQueue, data);
+ }
+
+ public virtual void EnqueueHigh(T data)
+ {
+ Enqueue(m_highQueue, data);
+ }
+
+ private void Enqueue(Queue q, T data)
+ {
+ lock (m_syncRoot)
+ {
+ m_lowQueue.Enqueue(data);
+ m_s.WaitOne(0);
+ m_s.Release();
+ }
+ }
+
+ public virtual T Dequeue()
+ {
+ return Dequeue(Timeout.Infinite);
+ }
+
+ public virtual T Dequeue(int tmo)
+ {
+ return Dequeue(TimeSpan.FromMilliseconds(tmo));
+ }
+
+ public virtual T Dequeue(TimeSpan wait)
+ {
+ T res = null;
+
+ if (!Dequeue(wait, ref res))
+ return null;
+
+ return res;
+ }
+
+ public bool Dequeue(int timeout, ref T res)
+ {
+ return Dequeue(TimeSpan.FromMilliseconds(timeout), ref res);
+ }
+
+ public bool Dequeue(TimeSpan wait, ref T res)
+ {
+ if (!m_s.WaitOne(wait))
+ return false;
+
+ lock (m_syncRoot)
+ {
+ if (m_highQueue.Count > 0)
+ res = m_highQueue.Dequeue();
+ else
+ res = m_lowQueue.Dequeue();
+
+ if (m_highQueue.Count == 0 || m_lowQueue.Count == 0)
+ return true;
+
+ m_s.Release();
+
+ return true;
+ }
+ }
+
+ public virtual void Clear()
+ {
+
+ lock (m_syncRoot)
+ {
+ // Make sure sem count is 0
+ m_s.WaitOne(0);
+
+ m_lowQueue.Clear();
+ m_highQueue.Clear();
+ }
+ }
+ }
}
--
cgit v1.1