further encapsulation of function in PacketQueue and PacketThrottle

afrisby
Sean Dague 2007-12-03 21:47:28 +00:00
parent 8f58a9a107
commit 14d0a2ac74
2 changed files with 172 additions and 4 deletions

View File

@ -221,9 +221,168 @@ namespace OpenSim.Region.ClientStack
} }
private void ThrottleCheck(ref PacketThrottle throttle, ref Queue<QueItem> q, QueItem item)
{
// 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()))
{
throttle.Add(item.Packet.ToBytes().Length);
TotalThrottle.Add(item.Packet.ToBytes().Length);
SendQueue.Enqueue(item);
}
else
{
q.Enqueue(item);
}
}
public void Add(QueItem item)
{
switch (item.throttleType)
{
case ThrottleOutPacketType.Resend:
ThrottleCheck(ref ResendThrottle, ref ResendOutgoingPacketQueue, item);
break;
case ThrottleOutPacketType.Texture:
ThrottleCheck(ref TextureThrottle, ref TextureOutgoingPacketQueue, item);
break;
case ThrottleOutPacketType.Task:
ThrottleCheck(ref TaskThrottle, ref TaskOutgoingPacketQueue, item);
break;
case ThrottleOutPacketType.Land:
ThrottleCheck(ref LandThrottle, ref LandOutgoingPacketQueue, item);
break;
case ThrottleOutPacketType.Asset:
ThrottleCheck(ref AssetThrottle, ref AssetOutgoingPacketQueue, item);
break;
case ThrottleOutPacketType.Cloud:
ThrottleCheck(ref CloudThrottle, ref CloudOutgoingPacketQueue, item);
break;
case ThrottleOutPacketType.Wind:
ThrottleCheck(ref WindThrottle, ref WindOutgoingPacketQueue, item);
break;
default:
// Acknowledgements and other such stuff should go directly to the blocking Queue
// Throttling them may and likely 'will' be problematic
SendQueue.Enqueue(item);
break;
}
} }
private int ScaleThrottle(int value, int curmax, int newmax)
{
return (int)(((float)value/(float)curmax) * newmax);
}
public void SetThrottleFromClient(Packet Pack)
{
//OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString());
AgentThrottlePacket atpack = (AgentThrottlePacket)Pack;
byte[] throttle = atpack.Throttle.Throttles;
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 libsecondlife.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;
/*
OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "Client AgentThrottle - Got throttle:resendbytes=" + tResend +
" landbytes=" + tLand +
" windbytes=" + tWind +
" cloudbytes=" + tCloud +
" taskbytes=" + tTask +
" texturebytes=" + tTexture +
" Assetbytes=" + tAsset +
" Allbytes=" + 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();
} }
}
}

View File

@ -89,7 +89,16 @@ namespace OpenSim.Region.ClientStack
public int Throttle public int Throttle
{ {
get {return throttle;} get {return throttle;}
set {throttle = value;} set
{
if (value > max) {
throttle = max;
} else if (value < min) {
throttle = min;
} else {
throttle = value;
}
}
} }
} }
} }