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.

LSLKeyTest
UbitUmarov 2016-08-07 17:07:09 +01:00
parent ff0ccf9c67
commit c255c23981
2 changed files with 46 additions and 40 deletions

View File

@ -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;
@ -4212,30 +4205,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// TODO: Remove this once we can build compressed updates // TODO: Remove this once we can build compressed updates
canUseCompressed = false; canUseCompressed = false;
if (!canUseImproved && !canUseCompressed) if (!canUseImproved && !canUseCompressed)
{ {
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,17 +4542,19 @@ 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)
ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
} }
internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories) internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories)
{ {
@ -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;

View File

@ -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,9 +806,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
else else
{
m_isQueueEmptyRunning = false; m_isQueueEmptyRunning = false;
}
} }
} }