From 7d6680b38a1220d6709cb189c0a2c430731f58cf Mon Sep 17 00:00:00 2001 From: Mike Rieker Date: Thu, 27 May 2010 21:28:47 -0400 Subject: fix hanging output throttle arithmetic had multiply overflow and subtract wrap-around errors --- .../Region/ClientStack/LindenUDP/TokenBucket.cs | 66 +++++++++------------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs index bdbd284..91e3d20 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs @@ -133,7 +133,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP this.parent = parent; MaxBurst = maxBurst; DripRate = dripRate; - lastDrip = Environment.TickCount & Int32.MaxValue; + lastDrip = Environment.TickCount; } /// @@ -144,40 +144,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// the bucket, otherwise false public bool RemoveTokens(int amount) { - bool dummy; - return RemoveTokens(amount, out dummy); - } - - /// - /// Remove a given number of tokens from the bucket - /// - /// Number of tokens to remove from the bucket - /// True if tokens were added to the bucket - /// during this call, otherwise false - /// True if the requested number of tokens were removed from - /// the bucket, otherwise false - public bool RemoveTokens(int amount, out bool dripSucceeded) - { if (maxBurst == 0) { - dripSucceeded = true; return true; } - dripSucceeded = Drip(); - - if (content - amount >= 0) + if (amount > maxBurst) { - if (parent != null && !parent.RemoveTokens(amount)) - return false; + throw new Exception("amount " + amount + " exceeds maxBurst " + maxBurst); + } - content -= amount; - return true; + Drip(); + + if (content < amount) + { + return false; } - else + + if (parent != null && !parent.RemoveTokens(amount)) { return false; } + + content -= amount; + return true; } /// @@ -193,25 +183,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP content = maxBurst; return true; } - else - { - int now = Environment.TickCount & Int32.MaxValue; - int deltaMS = now - lastDrip; - if (deltaMS <= 0) - { - if (deltaMS < 0) - lastDrip = now; - return false; - } + int now = Environment.TickCount; + int deltaMS = now - lastDrip; + lastDrip = now; - int dripAmount = deltaMS * tokensPerMS; - - content = Math.Min(content + dripAmount, maxBurst); - lastDrip = now; + if (deltaMS <= 0) + { + return false; + } - return true; + long dripAmount = (long)deltaMS * (long)tokensPerMS + (long)content; + if (dripAmount > maxBurst) + { + dripAmount = maxBurst; } + content = (int)dripAmount; + return true; } } } -- cgit v1.1