move updates from updates queues into udp queues acording to their payload estimated size and udp sending capability on a time slice, instead always moving a arbitrary number of updates.
parent
8d22b79ba4
commit
081c66631c
|
@ -3982,7 +3982,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
ResendPrimUpdate(update);
|
ResendPrimUpdate(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessEntityUpdates(int maxUpdates)
|
private void ProcessEntityUpdates(int maxUpdatesBytes)
|
||||||
{
|
{
|
||||||
OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
|
OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
|
||||||
OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
|
OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
|
||||||
|
@ -3996,16 +3996,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
|
|
||||||
// Check to see if this is a flush
|
// Check to see if this is a flush
|
||||||
if (maxUpdates <= 0)
|
if (maxUpdatesBytes <= 0)
|
||||||
{
|
{
|
||||||
maxUpdates = Int32.MaxValue;
|
maxUpdatesBytes = Int32.MaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int updatesThisCall = 0;
|
|
||||||
|
|
||||||
// We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
|
|
||||||
// condition where a kill can be processed before an out-of-date update for the same object.
|
|
||||||
// float avgTimeDilation = 0.0f;
|
|
||||||
EntityUpdate update;
|
EntityUpdate update;
|
||||||
Int32 timeinqueue; // this is just debugging code & can be dropped later
|
Int32 timeinqueue; // this is just debugging code & can be dropped later
|
||||||
|
|
||||||
|
@ -4018,25 +4013,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
ScenePresence mysp = (ScenePresence)SceneAgent;
|
ScenePresence mysp = (ScenePresence)SceneAgent;
|
||||||
if(mysp != null && !mysp.IsDeleted)
|
if(mysp != null && !mysp.IsDeleted)
|
||||||
{
|
{
|
||||||
cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance +16f;
|
cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f;
|
||||||
// mycamera = mysp.CameraPosition;
|
// mycamera = mysp.CameraPosition;
|
||||||
mypos = mysp.AbsolutePosition;
|
mypos = mysp.AbsolutePosition;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
doCulling = false;
|
doCulling = false;
|
||||||
|
|
||||||
while (updatesThisCall < maxUpdates)
|
while (maxUpdatesBytes > 0)
|
||||||
{
|
{
|
||||||
lock (m_entityUpdates.SyncRoot)
|
lock (m_entityUpdates.SyncRoot)
|
||||||
if (!m_entityUpdates.TryDequeue(out update, out timeinqueue))
|
if (!m_entityUpdates.TryDequeue(out update, out timeinqueue))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// avgTimeDilation += update.TimeDilation;
|
|
||||||
PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
|
PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
|
||||||
|
|
||||||
if(updateFlags.HasFlag(PrimUpdateFlags.Kill))
|
if(updateFlags.HasFlag(PrimUpdateFlags.Kill))
|
||||||
{
|
{
|
||||||
m_killRecord.Add(update.Entity.LocalId);
|
m_killRecord.Add(update.Entity.LocalId);
|
||||||
|
maxUpdatesBytes -= 30;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4158,8 +4153,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
++updatesThisCall;
|
|
||||||
|
|
||||||
#region UpdateFlags to packet type conversion
|
#region UpdateFlags to packet type conversion
|
||||||
|
|
||||||
bool canUseCompressed = true;
|
bool canUseCompressed = true;
|
||||||
|
@ -4217,25 +4210,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
if (update.Entity is ScenePresence)
|
if (update.Entity is ScenePresence)
|
||||||
{
|
{
|
||||||
objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
|
ObjectUpdatePacket.ObjectDataBlock ablock =
|
||||||
|
CreateAvatarUpdateBlock((ScenePresence)update.Entity);
|
||||||
|
objectUpdateBlocks.Value.Add(ablock);
|
||||||
|
maxUpdatesBytes -= ablock.Length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
|
ObjectUpdatePacket.ObjectDataBlock ablock =
|
||||||
|
CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId);
|
||||||
|
objectUpdateBlocks.Value.Add(ablock);
|
||||||
|
maxUpdatesBytes -= ablock.Length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!canUseImproved)
|
else if (!canUseImproved)
|
||||||
{
|
{
|
||||||
compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
|
ObjectUpdateCompressedPacket.ObjectDataBlock ablock =
|
||||||
|
CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags);
|
||||||
|
compressedUpdateBlocks.Value.Add(ablock);
|
||||||
|
maxUpdatesBytes -= ablock.Length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (update.Entity is ScenePresence)
|
if (update.Entity is ScenePresence)
|
||||||
|
{
|
||||||
// ALL presence updates go into a special list
|
// ALL presence updates go into a special list
|
||||||
terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
|
ImprovedTerseObjectUpdatePacket.ObjectDataBlock ablock =
|
||||||
|
CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
|
||||||
|
terseAgentUpdateBlocks.Value.Add(ablock);
|
||||||
|
maxUpdatesBytes -= ablock.Length;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
// Everything else goes here
|
// Everything else goes here
|
||||||
terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
|
ImprovedTerseObjectUpdatePacket.ObjectDataBlock ablock =
|
||||||
|
CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
|
||||||
|
terseUpdateBlocks.Value.Add(ablock);
|
||||||
|
maxUpdatesBytes -= ablock.Length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Block Construction
|
#endregion Block Construction
|
||||||
|
@ -4504,8 +4516,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// of updates converted to packets. Since we don't want packets
|
// of updates converted to packets. Since we don't want packets
|
||||||
// to sit in the queue with old data, only convert enough updates
|
// to sit in the queue with old data, only convert enough updates
|
||||||
// to packets that can be sent in 200ms.
|
// to packets that can be sent in 200ms.
|
||||||
private Int32 m_LastQueueFill = 0;
|
// private Int32 m_LastQueueFill = 0;
|
||||||
private Int32 m_maxUpdates = 0;
|
// private Int32 m_maxUpdates = 0;
|
||||||
|
|
||||||
void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
|
void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
|
||||||
{
|
{
|
||||||
|
@ -4516,7 +4528,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
// if (!m_udpServer.IsRunningOutbound)
|
// if (!m_udpServer.IsRunningOutbound)
|
||||||
// return;
|
// return;
|
||||||
|
/*
|
||||||
if (m_maxUpdates == 0 || m_LastQueueFill == 0)
|
if (m_maxUpdates == 0 || m_LastQueueFill == 0)
|
||||||
{
|
{
|
||||||
m_maxUpdates = m_udpServer.PrimUpdatesPerCallback;
|
m_maxUpdates = m_udpServer.PrimUpdatesPerCallback;
|
||||||
|
@ -4530,12 +4542,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
m_maxUpdates = Util.Clamp<Int32>(m_maxUpdates,10,500);
|
m_maxUpdates = Util.Clamp<Int32>(m_maxUpdates,10,500);
|
||||||
m_LastQueueFill = Util.EnvironmentTickCount();
|
m_LastQueueFill = Util.EnvironmentTickCount();
|
||||||
|
*/
|
||||||
|
int maxUpdateBytes = m_udpClient.GetCatBytesCanSend(ThrottleOutPacketType.Task, 30);
|
||||||
|
|
||||||
if (m_entityUpdates.Count > 0)
|
if (m_entityUpdates.Count > 0)
|
||||||
ProcessEntityUpdates(m_maxUpdates);
|
ProcessEntityUpdates(maxUpdateBytes);
|
||||||
|
|
||||||
if (m_entityProps.Count > 0)
|
if (m_entityProps.Count > 0)
|
||||||
ProcessEntityPropertyRequests(m_maxUpdates);
|
ProcessEntityPropertyRequests(maxUpdateBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
|
if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
|
||||||
|
@ -4723,7 +4737,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true));
|
m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessEntityPropertyRequests(int maxUpdates)
|
private void ProcessEntityPropertyRequests(int maxUpdateBytes)
|
||||||
{
|
{
|
||||||
OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>> objectFamilyBlocks =
|
OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>> objectFamilyBlocks =
|
||||||
new OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>>();
|
new OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>>();
|
||||||
|
@ -4740,8 +4754,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
EntityUpdate iupdate;
|
EntityUpdate iupdate;
|
||||||
Int32 timeinqueue; // this is just debugging code & can be dropped later
|
Int32 timeinqueue; // this is just debugging code & can be dropped later
|
||||||
|
|
||||||
int updatesThisCall = 0;
|
while (maxUpdateBytes > 0)
|
||||||
while (updatesThisCall < m_maxUpdates)
|
|
||||||
{
|
{
|
||||||
lock (m_entityProps.SyncRoot)
|
lock (m_entityProps.SyncRoot)
|
||||||
if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
|
if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
|
||||||
|
@ -4756,6 +4769,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
|
ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
|
||||||
objectFamilyBlocks.Value.Add(objPropDB);
|
objectFamilyBlocks.Value.Add(objPropDB);
|
||||||
familyUpdates.Value.Add(update);
|
familyUpdates.Value.Add(update);
|
||||||
|
maxUpdateBytes -= objPropDB.Length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4767,16 +4781,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
|
ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
|
||||||
objectPropertiesBlocks.Value.Add(objPropDB);
|
objectPropertiesBlocks.Value.Add(objPropDB);
|
||||||
propertyUpdates.Value.Add(update);
|
propertyUpdates.Value.Add(update);
|
||||||
|
maxUpdateBytes -= objPropDB.Length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updatesThisCall++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Int32 ppcnt = 0;
|
|
||||||
// Int32 pbcnt = 0;
|
|
||||||
|
|
||||||
if (objectPropertiesBlocks.IsValueCreated)
|
if (objectPropertiesBlocks.IsValueCreated)
|
||||||
{
|
{
|
||||||
List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value;
|
List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value;
|
||||||
|
|
|
@ -771,8 +771,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
RTO = Math.Min(RTO * 2, m_maxRTO);
|
RTO = Math.Min(RTO * 2, m_maxRTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int MIN_CALLBACK_MS = 20;
|
||||||
const int MIN_CALLBACK_MS = 10;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Does an early check to see if this queue empty callback is already
|
/// Does an early check to see if this queue empty callback is already
|
||||||
|
@ -807,11 +806,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
m_isQueueEmptyRunning = false;
|
m_isQueueEmptyRunning = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private bool m_isQueueEmptyRunning;
|
private bool m_isQueueEmptyRunning;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue