waste memory on a loss pool. Update resends need work.

This commit is contained in:
UbitUmarov
2020-09-17 20:18:56 +01:00
parent 8183945d5f
commit b9d97e4ee5
5 changed files with 108 additions and 12 deletions

View File

@@ -4776,7 +4776,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
uint priority = m_prioritizer.GetUpdatePriority(this, entity);
lock (m_entityUpdates.SyncRoot)
m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags));
m_entityUpdates.Enqueue(priority, EntityUpdatesPool.Get(entity, updateFlags));
}
/// <summary>
@@ -5481,7 +5481,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (terseUpdates != null)
{
int blocks = terseUpdates.Count;
List<EntityUpdate> tau = new List<EntityUpdate>(30);
//List<EntityUpdate> tau = new List<EntityUpdate>(30);
UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
@@ -5501,7 +5501,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos, (eu.Flags & PrimUpdateFlags.Textures) != 0);
if (pos < LLUDPServer.MAXPAYLOAD)
{
tau.Add(eu);
//tau.Add(eu);
++count;
--blocks;
}
@@ -5521,15 +5521,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
buf.DataLength = lastpos;
// zero encode is not as spec
m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, true);
//null, false, true);
//delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, true);
null, true);
tau = new List<EntityUpdate>(30);
tau.Add(eu);
//tau = new List<EntityUpdate>(30);
//tau.Add(eu);
count = 1;
--blocks;
buf = newbuf;
}
eu.Free(); //remove if using resend
}
if (count > 0)
@@ -5969,7 +5970,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
uint priority = 0; // time based ordering only
lock (m_entityProps.SyncRoot)
m_entityProps.Enqueue(priority, new EntityUpdate(entity, (PrimUpdateFlags)requestFlags, true, false));
m_entityProps.Enqueue(priority, EntityUpdatesPool.Get(entity, (PrimUpdateFlags)requestFlags, true, false));
}
private void ResendPropertyUpdate(EntityUpdate update)
@@ -6003,7 +6004,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
uint priority = 0; // time based ordering only
lock (m_entityProps.SyncRoot)
m_entityProps.Enqueue(priority, new EntityUpdate(entity,0,false,true));
m_entityProps.Enqueue(priority, EntityUpdatesPool.Get(entity,0,false,true));
}
static private readonly byte[] ObjectPropertyUpdateHeader = new byte[] {

View File

@@ -95,7 +95,14 @@ namespace OpenSim.Region.Framework.Scenes
public ISceneEntity Entity
{
get { return m_entity; }
get
{
return m_entity;
}
internal set
{
m_entity = value;
}
}
public PrimUpdateFlags Flags
@@ -143,6 +150,7 @@ namespace OpenSim.Region.Framework.Scenes
public void Free()
{
m_entity = null;
EntityUpdatesPool.Free(this);
}
public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags)
@@ -175,4 +183,82 @@ namespace OpenSim.Region.Framework.Scenes
return Comparer<ulong>.Default.Compare(this.EntryOrder, other.EntryOrder);
}
}
public static class EntityUpdatesPool
{
const int MAXSIZE = 32768;
const int PREALLOC = 16384;
private static readonly EntityUpdate[] m_pool = new EntityUpdate[MAXSIZE];
private static readonly object m_poollock = new object();
private static int m_poolPtr;
//private static int m_min = int.MaxValue;
//private static int m_max = int.MinValue;
static EntityUpdatesPool()
{
for(int i = 0; i < PREALLOC; ++i)
m_pool[i] = new EntityUpdate(null, 0);
m_poolPtr = PREALLOC - 1;
}
public static EntityUpdate Get(ISceneEntity entity, PrimUpdateFlags flags)
{
lock (m_poollock)
{
if (m_poolPtr >= 0)
{
EntityUpdate eu = m_pool[m_poolPtr];
m_pool[m_poolPtr] = null;
m_poolPtr--;
//if (m_min > m_poolPtr)
// m_min = m_poolPtr;
eu.Entity = entity;
eu.Flags = flags;
return eu;
}
}
return new EntityUpdate(entity, flags);
}
public static EntityUpdate Get(ISceneEntity entity, PrimUpdateFlags flags, bool sendfam, bool sendobj)
{
lock (m_poollock)
{
if (m_poolPtr >= 0)
{
EntityUpdate eu = m_pool[m_poolPtr];
m_pool[m_poolPtr] = null;
m_poolPtr--;
//if (m_min > m_poolPtr)
// m_min = m_poolPtr;
eu.Entity = entity;
eu.Flags = flags;
ObjectPropertyUpdateFlags tmp = 0;
if (sendfam)
tmp |= ObjectPropertyUpdateFlags.Family;
if (sendobj)
tmp |= ObjectPropertyUpdateFlags.Object;
eu.PropsFlags = tmp;
return eu;
}
}
return new EntityUpdate(entity, flags, sendfam, sendobj);
}
public static void Free(EntityUpdate eu)
{
lock (m_poollock)
{
if (m_poolPtr < MAXSIZE - 1)
{
m_poolPtr++;
//if (m_max < m_poolPtr)
// m_max = m_poolPtr;
m_pool[m_poolPtr] = eu;
}
}
}
}
}

View File

@@ -97,7 +97,12 @@ namespace OpenSim.Region.Framework.Scenes
public void Close()
{
for (int i = 0; i < m_heaps.Length; ++i)
{
foreach(EntityUpdate eu in m_heaps[i])
eu.Free();
m_heaps[i] = null;
}
m_heaps = null;
m_lookupTable.Clear();
m_lookupTable = null;
@@ -140,6 +145,7 @@ namespace OpenSim.Region.Framework.Scenes
pqueue = Util.Clamp<uint>(pqueue, 0, NumberOfQueues - 1);
value.Update(up, pqueue, entry);
up.Free();
lookup.Heap = m_heaps[pqueue];
lookup.Heap.Add(value, ref lookup.Handle);
@@ -167,6 +173,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (m_lookupTable.TryGetValue(localid, out lookup))
{
lookup.Heap[lookup.Handle].Free();
lookup.Heap.Remove(lookup.Handle);
m_lookupTable.Remove(localid);
}

View File

@@ -5348,7 +5348,7 @@ namespace OpenSim.Region.Framework.Scenes
public void SendUpdateToClient(IClientAPI remoteClient, PrimUpdateFlags update)
{
if (ParentGroup.IsDeleted)
if (ParentGroup.IsDeleted || !remoteClient.IsActive)
return;
if (Animations == null)

View File

@@ -1612,9 +1612,9 @@ namespace OpenSim.Region.Framework.Scenes
// Resume scripts
foreach (SceneObjectGroup sog in attachments)
{
sog.ScheduleGroupForFullUpdate();
sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
sog.ResumeScripts();
sog.ScheduleGroupForFullUpdate();
}
}
@@ -2235,9 +2235,11 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 look = Lookat;
look.Z = 0f;
look.Normalize();
if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01))
{
look = Velocity;
look.Z = 0f;
look.Normalize();
if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01) )
look = new Vector3(0.99f, 0.042f, 0);