diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 3a52f41f75..f7ab6a37c9 100755 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -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)); } /// @@ -5481,7 +5481,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (terseUpdates != null) { int blocks = terseUpdates.Count; - List tau = new List(30); + //List tau = new List(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(30); - tau.Add(eu); + //tau = new List(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[] { diff --git a/OpenSim/Region/Framework/Scenes/EntityUpdates.cs b/OpenSim/Region/Framework/Scenes/EntityUpdates.cs index 3271a6e822..ae6e51039c 100644 --- a/OpenSim/Region/Framework/Scenes/EntityUpdates.cs +++ b/OpenSim/Region/Framework/Scenes/EntityUpdates.cs @@ -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.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; + } + } + } + } } diff --git a/OpenSim/Region/Framework/Scenes/PriorityQueue.cs b/OpenSim/Region/Framework/Scenes/PriorityQueue.cs index 0f5b792951..614ce4b6b7 100644 --- a/OpenSim/Region/Framework/Scenes/PriorityQueue.cs +++ b/OpenSim/Region/Framework/Scenes/PriorityQueue.cs @@ -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(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); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b9323161fe..8f981d7e75 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -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) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index af5ecb4e7c..0cdc65147f 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -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);