From e7c877407f2a72a9519eb53debca5aeef20cded9 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 02:38:00 -0700 Subject: * Continued work on the new LLUDP implementation. Appears to be functioning, although not everything is reimplemented yet * Replaced logic in ThreadTracker with a call to System.Diagnostics that does the same thing * Added Util.StringToBytes256() and Util.StringToBytes1024() to clamp output at byte[256] and byte[1024], respectively * Fixed formatting for a MySQLAssetData error logging line --- .../Region/ClientStack/LindenUDP/LLPacketQueue.cs | 742 --------------------- 1 file changed, 742 deletions(-) delete mode 100644 OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs deleted file mode 100644 index 3eed2e0..0000000 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs +++ /dev/null @@ -1,742 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Threading; -using System.Timers; -using log4net; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Statistics; -using OpenSim.Framework.Statistics.Interfaces; -using Timer=System.Timers.Timer; - -namespace OpenSim.Region.ClientStack.LindenUDP -{ - public class LLPacketQueue : IPullStatsProvider, IDisposable - { - private static readonly ILog m_log - = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - /// - /// Is queueing enabled at all? - /// - private bool m_enabled = true; - - private OpenSim.Framework.BlockingQueue SendQueue; - - private Queue IncomingPacketQueue; - private Queue OutgoingPacketQueue; - private Queue ResendOutgoingPacketQueue; - private Queue LandOutgoingPacketQueue; - private Queue WindOutgoingPacketQueue; - private Queue CloudOutgoingPacketQueue; - private Queue TaskOutgoingPacketQueue; - private Queue TaskLowpriorityPacketQueue; - 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(); - - // All throttle times and number of bytes are calculated by dividing by this value - // This value also determines how many times per throttletimems the timer will run - // If throttleimems is 1000 ms, then the timer will fire every 1000/7 milliseconds - - private float throttleMultiplier = 2.0f; // Default value really doesn't matter. - private int throttleTimeDivisor = 7; - - private int throttletimems = 1000; - - internal LLPacketThrottle ResendThrottle; - internal LLPacketThrottle LandThrottle; - internal LLPacketThrottle WindThrottle; - internal LLPacketThrottle CloudThrottle; - internal LLPacketThrottle TaskThrottle; - internal LLPacketThrottle AssetThrottle; - internal LLPacketThrottle TextureThrottle; - internal LLPacketThrottle TotalThrottle; - - private Dictionary contents = new Dictionary(); - - // private long LastThrottle; - // private long ThrottleInterval; - private Timer throttleTimer; - - private UUID m_agentId; - - public event QueueEmpty OnQueueEmpty; - - public LLPacketQueue(UUID agentId, ClientStackUserSettings userSettings) - { - // While working on this, the BlockingQueue had me fooled for a bit. - // The Blocking queue causes the thread to stop until there's something - // in it to process. it's an on-purpose threadlock though because - // without it, the clientloop will suck up all sim resources. - - SendQueue = new OpenSim.Framework.BlockingQueue(); - - IncomingPacketQueue = new Queue(); - OutgoingPacketQueue = new Queue(); - ResendOutgoingPacketQueue = new Queue(); - LandOutgoingPacketQueue = new Queue(); - WindOutgoingPacketQueue = new Queue(); - CloudOutgoingPacketQueue = new Queue(); - TaskOutgoingPacketQueue = new Queue(); - TaskLowpriorityPacketQueue = new Queue(); - TextureOutgoingPacketQueue = new Queue(); - AssetOutgoingPacketQueue = new Queue(); - - // Store the throttle multiplier for posterity. - throttleMultiplier = userSettings.ClientThrottleMultipler; - - - int throttleMaxBPS = 1500000; - if (userSettings.TotalThrottleSettings != null) - throttleMaxBPS = userSettings.TotalThrottleSettings.Max; - - // Set up the throttle classes (min, max, current) in bits per second - ResendThrottle = new LLPacketThrottle(5000, throttleMaxBPS / 15, 16000, userSettings.ClientThrottleMultipler); - LandThrottle = new LLPacketThrottle(1000, throttleMaxBPS / 15, 2000, userSettings.ClientThrottleMultipler); - WindThrottle = new LLPacketThrottle(0, throttleMaxBPS / 15, 0, userSettings.ClientThrottleMultipler); - CloudThrottle = new LLPacketThrottle(0, throttleMaxBPS / 15, 0, userSettings.ClientThrottleMultipler); - TaskThrottle = new LLPacketThrottle(1000, throttleMaxBPS / 2, 3000, userSettings.ClientThrottleMultipler); - AssetThrottle = new LLPacketThrottle(1000, throttleMaxBPS / 2, 1000, userSettings.ClientThrottleMultipler); - TextureThrottle = new LLPacketThrottle(1000, throttleMaxBPS / 2, 4000, userSettings.ClientThrottleMultipler); - - - // Total Throttle trumps all - it is the number of bits in total that are allowed to go out per second. - - - ThrottleSettings totalThrottleSettings = userSettings.TotalThrottleSettings; - if (null == totalThrottleSettings) - { - totalThrottleSettings = new ThrottleSettings(0, throttleMaxBPS, 28000); - } - - TotalThrottle - = new LLPacketThrottle( - totalThrottleSettings.Min, totalThrottleSettings.Max, totalThrottleSettings.Current, - userSettings.ClientThrottleMultipler); - - throttleTimer = new Timer((int)(throttletimems / throttleTimeDivisor)); - throttleTimer.Elapsed += ThrottleTimerElapsed; - throttleTimer.Start(); - - // TIMERS needed for this - // LastThrottle = DateTime.Now.Ticks; - // ThrottleInterval = (long)(throttletimems/throttleTimeDivisor); - - m_agentId = agentId; - - if (StatsManager.SimExtraStats != null) - { - StatsManager.SimExtraStats.RegisterPacketQueueStatsProvider(m_agentId, this); - } - } - - /* STANDARD QUEUE MANIPULATION INTERFACES */ - - public void Enqueue(LLQueItem item) - { - if (!m_enabled) - { - return; - } - // We could micro lock, but that will tend to actually - // probably be worse than just synchronizing on SendQueue - - if (item == null) - { - SendQueue.Enqueue(item); - return; - } - - if (item.Incoming) - { - SendQueue.PriorityEnqueue(item); - return; - } - - if (item.Sequence != 0) - lock (contents) - { - if (contents.ContainsKey(item.Sequence)) - contents[item.Sequence] += 1; - else - contents.Add(item.Sequence, 1); - } - - lock (this) - { - switch (item.throttleType & ThrottleOutPacketType.TypeMask) - { - case ThrottleOutPacketType.Resend: - ThrottleCheck(ref ResendThrottle, ref ResendOutgoingPacketQueue, item, ThrottleOutPacketType.Resend); - break; - case ThrottleOutPacketType.Texture: - ThrottleCheck(ref TextureThrottle, ref TextureOutgoingPacketQueue, item, ThrottleOutPacketType.Texture); - break; - case ThrottleOutPacketType.Task: - if ((item.throttleType & ThrottleOutPacketType.LowPriority) != 0) - ThrottleCheck(ref TaskThrottle, ref TaskLowpriorityPacketQueue, item, ThrottleOutPacketType.Task); - else - ThrottleCheck(ref TaskThrottle, ref TaskOutgoingPacketQueue, item, ThrottleOutPacketType.Task); - break; - case ThrottleOutPacketType.Land: - ThrottleCheck(ref LandThrottle, ref LandOutgoingPacketQueue, item, ThrottleOutPacketType.Land); - break; - case ThrottleOutPacketType.Asset: - ThrottleCheck(ref AssetThrottle, ref AssetOutgoingPacketQueue, item, ThrottleOutPacketType.Asset); - break; - case ThrottleOutPacketType.Cloud: - ThrottleCheck(ref CloudThrottle, ref CloudOutgoingPacketQueue, item, ThrottleOutPacketType.Cloud); - break; - case ThrottleOutPacketType.Wind: - ThrottleCheck(ref WindThrottle, ref WindOutgoingPacketQueue, item, ThrottleOutPacketType.Wind); - break; - - default: - // Acknowledgements and other such stuff should go directly to the blocking Queue - // Throttling them may and likely 'will' be problematic - SendQueue.PriorityEnqueue(item); - break; - } - } - } - - public LLQueItem Dequeue() - { - while (true) - { - LLQueItem item = SendQueue.Dequeue(); - if (item == null) - return null; - if (item.Incoming) - return item; - item.TickCount = System.Environment.TickCount; - if (item.Sequence == 0) - return item; - lock (contents) - { - if (contents.ContainsKey(item.Sequence)) - { - if (contents[item.Sequence] == 1) - contents.Remove(item.Sequence); - else - contents[item.Sequence] -= 1; - return item; - } - } - } - } - - public void Cancel(uint sequence) - { - lock (contents) contents.Remove(sequence); - } - - public bool Contains(uint sequence) - { - lock (contents) return contents.ContainsKey(sequence); - } - - public void Flush() - { - lock (this) - { - // These categories do not contain transactional packets so we can safely drop any pending data in them - LandOutgoingPacketQueue.Clear(); - WindOutgoingPacketQueue.Clear(); - CloudOutgoingPacketQueue.Clear(); - TextureOutgoingPacketQueue.Clear(); - AssetOutgoingPacketQueue.Clear(); - - // Now comes the fun part.. we dump all remaining resend and task packets into the send queue - while (ResendOutgoingPacketQueue.Count > 0 || TaskOutgoingPacketQueue.Count > 0 || TaskLowpriorityPacketQueue.Count > 0) - { - if (ResendOutgoingPacketQueue.Count > 0) - SendQueue.Enqueue(ResendOutgoingPacketQueue.Dequeue()); - - if (TaskOutgoingPacketQueue.Count > 0) - SendQueue.PriorityEnqueue(TaskOutgoingPacketQueue.Dequeue()); - - if (TaskLowpriorityPacketQueue.Count > 0) - SendQueue.Enqueue(TaskLowpriorityPacketQueue.Dequeue()); - } - } - } - - public void WipeClean() - { - lock (this) - { - ResendOutgoingPacketQueue.Clear(); - LandOutgoingPacketQueue.Clear(); - WindOutgoingPacketQueue.Clear(); - CloudOutgoingPacketQueue.Clear(); - TaskOutgoingPacketQueue.Clear(); - TaskLowpriorityPacketQueue.Clear(); - TextureOutgoingPacketQueue.Clear(); - AssetOutgoingPacketQueue.Clear(); - SendQueue.Clear(); - lock (contents) contents.Clear(); - } - } - - public void Close() - { - Dispose(); - } - - public void Dispose() - { - Flush(); - WipeClean(); // I'm sure there's a dirty joke in here somewhere. -AFrisby - - m_enabled = false; - throttleTimer.Stop(); - throttleTimer.Close(); - - if (StatsManager.SimExtraStats != null) - { - StatsManager.SimExtraStats.DeregisterPacketQueueStatsProvider(m_agentId); - } - } - - private void ResetCounters() - { - ResendThrottle.Reset(); - LandThrottle.Reset(); - WindThrottle.Reset(); - CloudThrottle.Reset(); - TaskThrottle.Reset(); - AssetThrottle.Reset(); - TextureThrottle.Reset(); - TotalThrottle.Reset(); - } - - private bool PacketsWaiting() - { - return (ResendOutgoingPacketQueue.Count > 0 || - LandOutgoingPacketQueue.Count > 0 || - WindOutgoingPacketQueue.Count > 0 || - CloudOutgoingPacketQueue.Count > 0 || - TaskOutgoingPacketQueue.Count > 0 || - TaskLowpriorityPacketQueue.Count > 0 || - AssetOutgoingPacketQueue.Count > 0 || - TextureOutgoingPacketQueue.Count > 0); - } - - public void ProcessThrottle() - { - // I was considering this.. Will an event fire if the thread it's on is blocked? - - // Then I figured out.. it doesn't really matter.. because this thread won't be blocked for long - // The General overhead of the UDP protocol gets sent to the queue un-throttled by this - // so This'll pick up about around the right time. - - 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 - lock (this) - { - // this variable will be true if there was work done in the last execution of the - // loop, since each pass through the loop checks the queue length, we no longer - // need the check on entering the loop - bool qchanged = true; - - ResetCounters(); - - while (TotalThrottle.UnderLimit() && qchanged && throttleLoops <= MaxThrottleLoops) - { - qchanged = false; // We will break out of the loop if no work was accomplished - - throttleLoops++; - //Now comes the fun part.. we dump all our elements into m_packetQueue that we've saved up. - if ((ResendOutgoingPacketQueue.Count > 0) && ResendThrottle.UnderLimit()) - { - LLQueItem qpack = ResendOutgoingPacketQueue.Dequeue(); - - SendQueue.Enqueue(qpack); - TotalThrottle.AddBytes(qpack.Length); - ResendThrottle.AddBytes(qpack.Length); - - qchanged = true; - } - - if ((LandOutgoingPacketQueue.Count > 0) && LandThrottle.UnderLimit()) - { - LLQueItem qpack = LandOutgoingPacketQueue.Dequeue(); - - SendQueue.Enqueue(qpack); - TotalThrottle.AddBytes(qpack.Length); - LandThrottle.AddBytes(qpack.Length); - qchanged = true; - - if (LandOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Land)) - Empty.Add(ThrottleOutPacketType.Land); - } - - if ((WindOutgoingPacketQueue.Count > 0) && WindThrottle.UnderLimit()) - { - LLQueItem qpack = WindOutgoingPacketQueue.Dequeue(); - - SendQueue.Enqueue(qpack); - TotalThrottle.AddBytes(qpack.Length); - WindThrottle.AddBytes(qpack.Length); - qchanged = true; - - if (WindOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Wind)) - Empty.Add(ThrottleOutPacketType.Wind); - } - - if ((CloudOutgoingPacketQueue.Count > 0) && CloudThrottle.UnderLimit()) - { - LLQueItem qpack = CloudOutgoingPacketQueue.Dequeue(); - - SendQueue.Enqueue(qpack); - TotalThrottle.AddBytes(qpack.Length); - CloudThrottle.AddBytes(qpack.Length); - qchanged = true; - - if (CloudOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Cloud)) - Empty.Add(ThrottleOutPacketType.Cloud); - } - - if ((TaskOutgoingPacketQueue.Count > 0 || TaskLowpriorityPacketQueue.Count > 0) && TaskThrottle.UnderLimit()) - { - LLQueItem qpack; - if (TaskOutgoingPacketQueue.Count > 0) - { - qpack = TaskOutgoingPacketQueue.Dequeue(); - SendQueue.PriorityEnqueue(qpack); - } - else - { - qpack = TaskLowpriorityPacketQueue.Dequeue(); - SendQueue.Enqueue(qpack); - } - - TotalThrottle.AddBytes(qpack.Length); - TaskThrottle.AddBytes(qpack.Length); - qchanged = true; - - if (TaskOutgoingPacketQueue.Count == 0 && TaskLowpriorityPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Task)) - Empty.Add(ThrottleOutPacketType.Task); - } - - if ((TextureOutgoingPacketQueue.Count > 0) && TextureThrottle.UnderLimit()) - { - LLQueItem qpack = TextureOutgoingPacketQueue.Dequeue(); - - SendQueue.Enqueue(qpack); - TotalThrottle.AddBytes(qpack.Length); - TextureThrottle.AddBytes(qpack.Length); - qchanged = true; - - if (TextureOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Texture)) - Empty.Add(ThrottleOutPacketType.Texture); - } - - if ((AssetOutgoingPacketQueue.Count > 0) && AssetThrottle.UnderLimit()) - { - LLQueItem qpack = AssetOutgoingPacketQueue.Dequeue(); - - SendQueue.Enqueue(qpack); - TotalThrottle.AddBytes(qpack.Length); - AssetThrottle.AddBytes(qpack.Length); - qchanged = true; - - if (AssetOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Asset)) - Empty.Add(ThrottleOutPacketType.Asset); - } - } - // m_log.Info("[THROTTLE]: Processed " + throttleLoops + " packets"); - - e = new List(Empty); - Empty.Clear(); - } - - foreach (ThrottleOutPacketType t in e) - { - if (GetQueueCount(t) == 0) - TriggerOnQueueEmpty(t); - } - } - - private void TriggerOnQueueEmpty(ThrottleOutPacketType queue) - { - QueueEmpty handlerQueueEmpty = OnQueueEmpty; - - if (handlerQueueEmpty != null) - handlerQueueEmpty(queue); - } - - private void ThrottleTimerElapsed(object sender, ElapsedEventArgs e) - { - // just to change the signature, and that ProcessThrottle - // will be used elsewhere possibly - ProcessThrottle(); - } - - 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 - // it up directly. This basically short cuts having to - // wait for the timer to fire to put things into the - // output queue - - if ((q.Count == 0) && (throttle.UnderLimit())) - { - try - { - Monitor.Enter(this); - throttle.AddBytes(item.Length); - TotalThrottle.AddBytes(item.Length); - SendQueue.Enqueue(item); - lock (this) - { - if (!Empty.Contains(itemType)) - Empty.Add(itemType); - } - } - catch (Exception e) - { - // Probably a serialization exception - m_log.WarnFormat("ThrottleCheck: {0}", e.ToString()); - } - finally - { - Monitor.Pulse(this); - Monitor.Exit(this); - } - } - else - { - q.Enqueue(item); - } - } - - private static int ScaleThrottle(int value, int curmax, int newmax) - { - return (int)((value / (float)curmax) * newmax); - } - - public byte[] GetThrottlesPacked(float multiplier) - { - int singlefloat = 4; - float tResend = ResendThrottle.Throttle*multiplier; - float tLand = LandThrottle.Throttle*multiplier; - float tWind = WindThrottle.Throttle*multiplier; - float tCloud = CloudThrottle.Throttle*multiplier; - float tTask = TaskThrottle.Throttle*multiplier; - float tTexture = TextureThrottle.Throttle*multiplier; - float tAsset = AssetThrottle.Throttle*multiplier; - - byte[] throttles = new byte[singlefloat*7]; - int i = 0; - Buffer.BlockCopy(BitConverter.GetBytes(tResend), 0, throttles, singlefloat*i, singlefloat); - i++; - Buffer.BlockCopy(BitConverter.GetBytes(tLand), 0, throttles, singlefloat*i, singlefloat); - i++; - Buffer.BlockCopy(BitConverter.GetBytes(tWind), 0, throttles, singlefloat*i, singlefloat); - i++; - Buffer.BlockCopy(BitConverter.GetBytes(tCloud), 0, throttles, singlefloat*i, singlefloat); - i++; - Buffer.BlockCopy(BitConverter.GetBytes(tTask), 0, throttles, singlefloat*i, singlefloat); - i++; - Buffer.BlockCopy(BitConverter.GetBytes(tTexture), 0, throttles, singlefloat*i, singlefloat); - i++; - Buffer.BlockCopy(BitConverter.GetBytes(tAsset), 0, throttles, singlefloat*i, singlefloat); - - return throttles; - } - - public void SetThrottleFromClient(byte[] throttle) - { - // From mantis http://opensimulator.org/mantis/view.php?id=1374 - // it appears that sometimes we are receiving empty throttle byte arrays. - // TODO: Investigate this behaviour - if (throttle.Length == 0) - { - m_log.Warn("[PACKET QUEUE]: SetThrottleFromClient unexpectedly received a throttle byte array containing no elements!"); - return; - } - - int tResend = -1; - int tLand = -1; - int tWind = -1; - int tCloud = -1; - int tTask = -1; - int tTexture = -1; - int tAsset = -1; - int tall = -1; - int singlefloat = 4; - - //Agent Throttle Block contains 7 single floatingpoint values. - int j = 0; - - // Some Systems may be big endian... - // it might be smart to do this check more often... - if (!BitConverter.IsLittleEndian) - for (int i = 0; i < 7; i++) - Array.Reverse(throttle, j + i*singlefloat, singlefloat); - - // values gotten from OpenMetaverse.org/wiki/Throttle. Thanks MW_ - // bytes - // Convert to integer, since.. the full fp space isn't used. - tResend = (int) BitConverter.ToSingle(throttle, j); - j += singlefloat; - tLand = (int) BitConverter.ToSingle(throttle, j); - j += singlefloat; - tWind = (int) BitConverter.ToSingle(throttle, j); - j += singlefloat; - tCloud = (int) BitConverter.ToSingle(throttle, j); - j += singlefloat; - tTask = (int) BitConverter.ToSingle(throttle, j); - j += singlefloat; - tTexture = (int) BitConverter.ToSingle(throttle, j); - j += singlefloat; - tAsset = (int) BitConverter.ToSingle(throttle, j); - - tall = tResend + tLand + tWind + tCloud + tTask + tTexture + tAsset; - - /* - m_log.Info("[CLIENT]: Client AgentThrottle - Got throttle:resendbits=" + tResend + - " landbits=" + tLand + - " windbits=" + tWind + - " cloudbits=" + tCloud + - " taskbits=" + tTask + - " texturebits=" + tTexture + - " Assetbits=" + tAsset + - " Allbits=" + tall); - */ - - - // Total Sanity - // Make sure that the client sent sane total values. - - // If the client didn't send acceptable values.... - // Scale the clients values down until they are acceptable. - - if (tall <= TotalThrottle.Max) - { - ResendThrottle.Throttle = tResend; - LandThrottle.Throttle = tLand; - WindThrottle.Throttle = tWind; - CloudThrottle.Throttle = tCloud; - TaskThrottle.Throttle = tTask; - TextureThrottle.Throttle = tTexture; - AssetThrottle.Throttle = tAsset; - TotalThrottle.Throttle = tall; - } -// else if (tall < 1) -// { -// // client is stupid, penalize him by minning everything -// ResendThrottle.Throttle = ResendThrottle.Min; -// LandThrottle.Throttle = LandThrottle.Min; -// WindThrottle.Throttle = WindThrottle.Min; -// CloudThrottle.Throttle = CloudThrottle.Min; -// TaskThrottle.Throttle = TaskThrottle.Min; -// TextureThrottle.Throttle = TextureThrottle.Min; -// AssetThrottle.Throttle = AssetThrottle.Min; -// TotalThrottle.Throttle = TotalThrottle.Min; -// } - else - { - // we're over so figure out percentages and use those - ResendThrottle.Throttle = tResend; - - LandThrottle.Throttle = ScaleThrottle(tLand, tall, TotalThrottle.Max); - WindThrottle.Throttle = ScaleThrottle(tWind, tall, TotalThrottle.Max); - CloudThrottle.Throttle = ScaleThrottle(tCloud, tall, TotalThrottle.Max); - TaskThrottle.Throttle = ScaleThrottle(tTask, tall, TotalThrottle.Max); - TextureThrottle.Throttle = ScaleThrottle(tTexture, tall, TotalThrottle.Max); - AssetThrottle.Throttle = ScaleThrottle(tAsset, tall, TotalThrottle.Max); - TotalThrottle.Throttle = TotalThrottle.Max; - } - // effectively wiggling the slider causes things reset -// ResetCounters(); // DO NOT reset, better to send less for one period than more - } - - // See IPullStatsProvider - public string GetStats() - { - return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", - SendQueue.Count(), - IncomingPacketQueue.Count, - OutgoingPacketQueue.Count, - ResendOutgoingPacketQueue.Count, - LandOutgoingPacketQueue.Count, - WindOutgoingPacketQueue.Count, - CloudOutgoingPacketQueue.Count, - TaskOutgoingPacketQueue.Count, - TextureOutgoingPacketQueue.Count, - AssetOutgoingPacketQueue.Count); - } - - public LLQueItem[] GetQueueArray() - { - return SendQueue.GetQueueArray(); - } - - public float ThrottleMultiplier - { - get { return throttleMultiplier; } - } - - public int GetQueueCount(ThrottleOutPacketType queue) - { - switch (queue) - { - case ThrottleOutPacketType.Land: - return LandOutgoingPacketQueue.Count; - case ThrottleOutPacketType.Wind: - return WindOutgoingPacketQueue.Count; - case ThrottleOutPacketType.Cloud: - return CloudOutgoingPacketQueue.Count; - case ThrottleOutPacketType.Task: - return TaskOutgoingPacketQueue.Count; - case ThrottleOutPacketType.Texture: - return TextureOutgoingPacketQueue.Count; - case ThrottleOutPacketType.Asset: - return AssetOutgoingPacketQueue.Count; - } - - return 0; - } - } -} -- cgit v1.1