diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs index 1448722fce..b958b011fb 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs @@ -232,6 +232,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_packetNumber = m_requestedPacketNumber; } + + if (m_imageManager.Client.PacketHandler.GetQueueCount(ThrottleOutPacketType.Texture) == 0) + { + m_log.Debug("No textures queued, sending one packet to kickstart it"); + SendPacket(m_imageManager.Client); + } } } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 460f94edae..23fa1a3eab 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -81,8 +81,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP private List m_primFullUpdates = new List(); - private Timer m_textureRequestTimer; - private bool m_clientBlocked; private int m_probesWithNoIngressPackets; @@ -143,9 +141,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected int m_primTerseUpdateRate = 10; protected int m_primFullUpdateRate = 14; - protected int m_textureRequestRate = 100; - protected int m_textureSendLimit = 10; - protected int m_textureDataLimit = 5; + protected int m_textureSendLimit = 100; + protected int m_textureDataLimit = 10; protected int m_packetMTU = 1400; @@ -534,6 +531,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_PacketHandler = new LLPacketHandler(this, m_networkServer, userSettings); m_PacketHandler.SynchronizeClient = SynchronizeClient; m_PacketHandler.OnPacketStats += PopulateStats; + m_PacketHandler.OnQueueEmpty += HandleQueueEmpty; if (scene.Config != null) { @@ -555,9 +553,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primFullUpdateRate = clientConfig.GetInt("FullUpdateRate", m_primFullUpdateRate); - m_textureRequestRate = clientConfig.GetInt("TextureRequestRate", - m_textureRequestRate); - m_textureSendLimit = clientConfig.GetInt("TextureSendLimit", m_textureSendLimit); @@ -607,9 +602,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (m_primFullUpdateTimer.Enabled) lock (m_primFullUpdateTimer) m_primFullUpdateTimer.Stop(); - if (m_textureRequestTimer.Enabled) - lock (m_textureRequestTimer) - m_textureRequestTimer.Stop(); // This is just to give the client a reasonable chance of // flushing out all it's packets. There should probably @@ -706,10 +698,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (m_primFullUpdateTimer.Enabled) lock (m_primFullUpdateTimer) m_primFullUpdateTimer.Stop(); - - if (m_textureRequestTimer.Enabled) - lock (m_textureRequestTimer) - m_textureRequestTimer.Stop(); } public void Restart() @@ -732,11 +720,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); m_primFullUpdateTimer.AutoReset = false; - - m_textureRequestTimer = new Timer(m_textureRequestRate); - m_textureRequestTimer.Elapsed += new ElapsedEventHandler(ProcessTextureRequests); - m_textureRequestTimer.AutoReset = false; - } private void Terminate() @@ -747,7 +730,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_avatarTerseUpdateTimer.Close(); m_primTerseUpdateTimer.Close(); m_primFullUpdateTimer.Close(); - m_textureRequestTimer.Close(); m_PacketHandler.OnPacketStats -= PopulateStats; m_PacketHandler.Dispose(); @@ -982,10 +964,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); m_primFullUpdateTimer.AutoReset = false; - m_textureRequestTimer = new Timer(m_textureRequestRate); - m_textureRequestTimer.Elapsed += new ElapsedEventHandler(ProcessTextureRequests); - m_textureRequestTimer.AutoReset = false; - m_scene.AddNewClient(this); RefreshGroupMembership(); @@ -1057,26 +1035,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - protected virtual void TextureRequestHandler() - { - m_log.DebugFormat("[TRH] Thread started"); - while (m_imageManager != null) - { - try - { - while (m_imageManager != null) - { - } - } - catch (Exception e) - { - m_log.WarnFormat("[TRH] Exception in handler loop: {0}", e.Message); - m_log.Debug(e); - } - } - m_log.DebugFormat("[TRH] Thread terminated"); - } - # endregion // Previously ClientView.API partial class @@ -3176,16 +3134,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Unlike the other timers, this one is only started after // the first request is seen. - void ProcessTextureRequests(object sender, ElapsedEventArgs e) + void HandleQueueEmpty(ThrottleOutPacketType queue) + { + switch (queue) + { + case ThrottleOutPacketType.Texture: + m_log.Debug("Texture queue empty"); + ProcessTextureRequests(); + break; + } + } + + void ProcessTextureRequests() { if (m_imageManager != null) { - if (m_imageManager.ProcessImageQueue(m_textureSendLimit, - m_textureDataLimit)) - { - lock (m_textureRequestTimer) - m_textureRequestTimer.Start(); - } + m_imageManager.ProcessImageQueue(m_textureSendLimit, + m_textureDataLimit); } } @@ -6638,8 +6603,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (m_imageManager != null) { m_imageManager.EnqueueReq(args); - lock (m_textureRequestTimer) - m_textureRequestTimer.Start(); } } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs index 70af8e87a8..1556d01b16 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs @@ -65,6 +65,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_j2kDecodeModule = pJ2kDecodeModule; } + public LLClientView Client + { + get { return m_client; } + } + public void EnqueueReq(TextureRequestArgs newRequest) { //newRequest is the properties of our new texture fetch request. @@ -207,8 +212,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP threshold = 10; //Uncomment this to see what the texture stack is doing - //m_log.Debug("Queue: " + m_client.PacketHandler.PacketQueue.TextureOutgoingPacketQueueCount.ToString() + " Threshold: " + threshold.ToString() + " outstanding: " + m_outstandingtextures.ToString()); - if (m_client.PacketHandler.PacketQueue.TextureOutgoingPacketQueueCount < threshold) + //m_log.Debug("Queue: " + m_client.PacketHandler.PacketQueue.getQueueCount(ThrottleOutPacketType.Texture).ToString() + " Threshold: " + threshold.ToString() + " outstanding: " + m_outstandingtextures.ToString()); + if (m_client.PacketHandler.PacketQueue.GetQueueCount(ThrottleOutPacketType.Texture) < threshold) { while (m_priorityQueue.Count > 0) { diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs index d4d654fba3..8484846c8a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs @@ -62,6 +62,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP private Queue TextureOutgoingPacketQueue; private Queue AssetOutgoingPacketQueue; + private List Empty = new List(); + // m_log.Info("[THROTTLE]: Entering Throttle"); // private Dictionary PendingAcks = new Dictionary(); // private Dictionary NeedAck = new Dictionary(); @@ -85,20 +87,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP private Dictionary contents = new Dictionary(); - /// - /// The number of packets in the OutgoingPacketQueue - /// - /// - internal int TextureOutgoingPacketQueueCount - { - get - { - if (TextureOutgoingPacketQueue == null) - return 0; - return TextureOutgoingPacketQueue.Count; - } - } - // private long LastThrottle; // private long ThrottleInterval; private Timer throttleTimer; @@ -212,28 +200,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP switch (item.throttleType & ThrottleOutPacketType.TypeMask) { case ThrottleOutPacketType.Resend: - ThrottleCheck(ref ResendThrottle, ref ResendOutgoingPacketQueue, item); + ThrottleCheck(ref ResendThrottle, ref ResendOutgoingPacketQueue, item, ThrottleOutPacketType.Resend); break; case ThrottleOutPacketType.Texture: - ThrottleCheck(ref TextureThrottle, ref TextureOutgoingPacketQueue, item); + ThrottleCheck(ref TextureThrottle, ref TextureOutgoingPacketQueue, item, ThrottleOutPacketType.Texture); break; case ThrottleOutPacketType.Task: if ((item.throttleType & ThrottleOutPacketType.LowPriority) != 0) - ThrottleCheck(ref TaskThrottle, ref TaskLowpriorityPacketQueue, item); + ThrottleCheck(ref TaskThrottle, ref TaskLowpriorityPacketQueue, item, ThrottleOutPacketType.Task); else - ThrottleCheck(ref TaskThrottle, ref TaskOutgoingPacketQueue, item); + ThrottleCheck(ref TaskThrottle, ref TaskOutgoingPacketQueue, item, ThrottleOutPacketType.Task); break; case ThrottleOutPacketType.Land: - ThrottleCheck(ref LandThrottle, ref LandOutgoingPacketQueue, item); + ThrottleCheck(ref LandThrottle, ref LandOutgoingPacketQueue, item, ThrottleOutPacketType.Land); break; case ThrottleOutPacketType.Asset: - ThrottleCheck(ref AssetThrottle, ref AssetOutgoingPacketQueue, item); + ThrottleCheck(ref AssetThrottle, ref AssetOutgoingPacketQueue, item, ThrottleOutPacketType.Asset); break; case ThrottleOutPacketType.Cloud: - ThrottleCheck(ref CloudThrottle, ref CloudOutgoingPacketQueue, item); + ThrottleCheck(ref CloudThrottle, ref CloudOutgoingPacketQueue, item, ThrottleOutPacketType.Cloud); break; case ThrottleOutPacketType.Wind: - ThrottleCheck(ref WindThrottle, ref WindOutgoingPacketQueue, item); + ThrottleCheck(ref WindThrottle, ref WindOutgoingPacketQueue, item, ThrottleOutPacketType.Wind); break; default: @@ -408,6 +396,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP int MaxThrottleLoops = 4550; // 50*7 packets can be dequeued at once. int throttleLoops = 0; + List e; // We're going to dequeue all of the saved up packets until // we've hit the throttle limit or there's no more packets to send @@ -420,8 +409,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP ResetCounters(); - List Empty = new List(); - // m_log.Info("[THROTTLE]: Entering Throttle"); while (TotalThrottle.UnderLimit() && qchanged && throttleLoops <= MaxThrottleLoops) { qchanged = false; // We will break out of the loop if no work was accomplished @@ -448,7 +435,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP LandThrottle.AddBytes(qpack.Length); qchanged = true; - if (LandOutgoingPacketQueue.Count == 0) + if (LandOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Land)) Empty.Add(ThrottleOutPacketType.Land); } @@ -461,7 +448,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP WindThrottle.AddBytes(qpack.Length); qchanged = true; - if (WindOutgoingPacketQueue.Count == 0) + if (WindOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Wind)) Empty.Add(ThrottleOutPacketType.Wind); } @@ -474,7 +461,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP CloudThrottle.AddBytes(qpack.Length); qchanged = true; - if (CloudOutgoingPacketQueue.Count == 0) + if (CloudOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Cloud)) Empty.Add(ThrottleOutPacketType.Cloud); } @@ -496,7 +483,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP TaskThrottle.AddBytes(qpack.Length); qchanged = true; - if (TaskOutgoingPacketQueue.Count == 0 && TaskLowpriorityPacketQueue.Count == 0) + if (TaskOutgoingPacketQueue.Count == 0 && TaskLowpriorityPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Task)) Empty.Add(ThrottleOutPacketType.Task); } @@ -509,7 +496,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP TextureThrottle.AddBytes(qpack.Length); qchanged = true; - if (TextureOutgoingPacketQueue.Count == 0) + if (TextureOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Texture)) Empty.Add(ThrottleOutPacketType.Texture); } @@ -522,16 +509,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP AssetThrottle.AddBytes(qpack.Length); qchanged = true; - if (AssetOutgoingPacketQueue.Count == 0) + if (AssetOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Asset)) Empty.Add(ThrottleOutPacketType.Asset); } } // m_log.Info("[THROTTLE]: Processed " + throttleLoops + " packets"); - foreach (ThrottleOutPacketType t in Empty) - { + e = new List(Empty); + Empty.Clear(); + } + + foreach (ThrottleOutPacketType t in e) + { + if (GetQueueCount(t) == 0) TriggerOnQueueEmpty(t); - } } } @@ -552,7 +543,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ProcessThrottle(); } - private void ThrottleCheck(ref LLPacketThrottle throttle, ref Queue q, LLQueItem item) + private void ThrottleCheck(ref LLPacketThrottle throttle, ref Queue q, LLQueItem item, ThrottleOutPacketType itemType) { // The idea.. is if the packet throttle queues are empty // and the client is under throttle for the type. Queue @@ -568,6 +559,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP throttle.AddBytes(item.Length); TotalThrottle.AddBytes(item.Length); SendQueue.Enqueue(item); + lock (this) + { + if (!Empty.Contains(itemType)) + Empty.Add(itemType); + } } catch (Exception e) { diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 2be8c069a8..1f42ef2bb8 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -1352,11 +1352,6 @@ ;PacketMTU = 1400 - ; TextureUpdateRate (mS) determines how many times per second - ; texture send processing will occur. The default is 100mS. - ; - ;TextureRequestRate = 100 - ; TextureSendLimit determines how many different textures ; will be considered on each cycle. Textures are selected ; by priority. The old mechanism specified a value of 10 for