fix hanging output throttle arithmetic

had multiply overflow and subtract wrap-around errors
avinationmerge
Mike Rieker 2010-05-27 21:28:47 -04:00
parent 297bcb5c3d
commit 7d6680b38a
1 changed files with 30 additions and 42 deletions

View File

@ -133,7 +133,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
this.parent = parent; this.parent = parent;
MaxBurst = maxBurst; MaxBurst = maxBurst;
DripRate = dripRate; DripRate = dripRate;
lastDrip = Environment.TickCount & Int32.MaxValue; lastDrip = Environment.TickCount;
} }
/// <summary> /// <summary>
@ -143,42 +143,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <returns>True if the requested number of tokens were removed from /// <returns>True if the requested number of tokens were removed from
/// the bucket, otherwise false</returns> /// the bucket, otherwise false</returns>
public bool RemoveTokens(int amount) public bool RemoveTokens(int amount)
{
bool dummy;
return RemoveTokens(amount, out dummy);
}
/// <summary>
/// Remove a given number of tokens from the bucket
/// </summary>
/// <param name="amount">Number of tokens to remove from the bucket</param>
/// <param name="dripSucceeded">True if tokens were added to the bucket
/// during this call, otherwise false</param>
/// <returns>True if the requested number of tokens were removed from
/// the bucket, otherwise false</returns>
public bool RemoveTokens(int amount, out bool dripSucceeded)
{ {
if (maxBurst == 0) if (maxBurst == 0)
{ {
dripSucceeded = true;
return true; return true;
} }
dripSucceeded = Drip(); if (amount > maxBurst)
{
if (content - amount >= 0) throw new Exception("amount " + amount + " exceeds maxBurst " + maxBurst);
}
Drip();
if (content < amount)
{ {
if (parent != null && !parent.RemoveTokens(amount))
return false; return false;
}
if (parent != null && !parent.RemoveTokens(amount))
{
return false;
}
content -= amount; content -= amount;
return true; return true;
} }
else
{
return false;
}
}
/// <summary> /// <summary>
/// Add tokens to the bucket over time. The number of tokens added each /// Add tokens to the bucket over time. The number of tokens added each
@ -193,25 +183,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
content = maxBurst; content = maxBurst;
return true; return true;
} }
else
{ int now = Environment.TickCount;
int now = Environment.TickCount & Int32.MaxValue;
int deltaMS = now - lastDrip; int deltaMS = now - lastDrip;
lastDrip = now;
if (deltaMS <= 0) if (deltaMS <= 0)
{ {
if (deltaMS < 0)
lastDrip = now;
return false; return false;
} }
int dripAmount = deltaMS * tokensPerMS; long dripAmount = (long)deltaMS * (long)tokensPerMS + (long)content;
if (dripAmount > maxBurst)
content = Math.Min(content + dripAmount, maxBurst); {
lastDrip = now; dripAmount = maxBurst;
}
content = (int)dripAmount;
return true; return true;
} }
} }
}
} }