diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 7042c9a228..75a47d5379 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 @@ -1471,8 +1478,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP Packet packet = incomingPacket.Packet; LLClientView client = incomingPacket.Client; - if (client.IsActive) - { +// if (client.IsActive) +// { m_currentIncomingClient = client; try @@ -1499,13 +1506,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_currentIncomingClient = null; } - } - else - { - m_log.DebugFormat( - "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", - packet.Type, client.Name, m_scene.RegionInfo.RegionName); - } +// } +// else +// { +// m_log.DebugFormat( +// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", +// packet.Type, client.Name, m_scene.RegionInfo.RegionName); +// } } protected void LogoutHandler(IClientAPI client) @@ -1519,4 +1526,112 @@ 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; + + try + { + m_s.Release(); + } + catch + { + } + + 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(); + } + } + } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fe34ad4325..df4bd0d2e1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3034,7 +3034,8 @@ namespace OpenSim.Region.Framework.Scenes /// public virtual void DetachFromBackup() { - m_scene.SceneGraph.FireDetachFromBackup(this); + if (m_scene != null) + m_scene.SceneGraph.FireDetachFromBackup(this); if (m_isBackedUp && Scene != null) m_scene.EventManager.OnBackup -= ProcessBackup;