From 588361e2a2398b963871762c2b5485c6a086cf47 Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Fri, 23 Oct 2009 01:02:36 -0700
Subject: Experimental change to use an immutable array for iterating
 ScenePresences, avoiding locking and copying the list each time it is
 accessed

---
 .../Region/ClientStack/LindenUDP/LLClientView.cs   | 141 +++++++++---------
 .../CoreModules/Avatar/Combat/CombatModule.cs      |   8 +-
 .../CoreModules/Avatar/Dialog/DialogModule.cs      |  17 ++-
 .../World/Estate/EstateManagementModule.cs         |   7 +-
 OpenSim/Region/Framework/Scenes/Scene.cs           |  25 ++--
 OpenSim/Region/Framework/Scenes/SceneGraph.cs      | 160 +++++++++++----------
 OpenSim/Region/Framework/Scenes/SceneManager.cs    |  53 +++----
 .../Region/Framework/Scenes/SceneObjectGroup.cs    |   4 +-
 OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 121 ++++++++--------
 OpenSim/Region/Framework/Scenes/ScenePresence.cs   |  21 +--
 .../Shared/Api/Implementation/LSL_Api.cs           |   8 +-
 .../Api/Implementation/Plugins/SensorRepeat.cs     |  13 +-
 .../Region/UserStatistics/ActiveConnectionsAJAX.cs |  14 +-
 13 files changed, 308 insertions(+), 284 deletions(-)

diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 5acf25f..e81ff4b 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -4434,6 +4434,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
         protected virtual void RegisterLocalPacketHandlers()
         {
             AddLocalPacketHandler(PacketType.LogoutRequest, Logout);
+            AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate);
             AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect);
             AddLocalPacketHandler(PacketType.AgentCachedTexture, AgentTextureCached);
             AddLocalPacketHandler(PacketType.MultipleObjectUpdate, MultipleObjUpdate);
@@ -4446,6 +4447,75 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 
         #region Packet Handlers
 
+        private bool HandleAgentUpdate(IClientAPI sener, Packet Pack)
+        {
+            if (OnAgentUpdate != null)
+            {
+                bool update = false;
+                AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack;
+
+                #region Packet Session and User Check
+                if (agenUpdate.AgentData.SessionID != SessionId || agenUpdate.AgentData.AgentID != AgentId)
+                    return false;
+                #endregion
+
+                AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData;
+
+                // We can only check when we have something to check
+                // against.
+
+                if (lastarg != null)
+                {
+                    update =
+                       (
+                        (x.BodyRotation != lastarg.BodyRotation) ||
+                        (x.CameraAtAxis != lastarg.CameraAtAxis) ||
+                        (x.CameraCenter != lastarg.CameraCenter) ||
+                        (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
+                        (x.CameraUpAxis != lastarg.CameraUpAxis) ||
+                        (x.ControlFlags != lastarg.ControlFlags) ||
+                        (x.Far != lastarg.Far) ||
+                        (x.Flags != lastarg.Flags) ||
+                        (x.State != lastarg.State) ||
+                        (x.HeadRotation != lastarg.HeadRotation) ||
+                        (x.SessionID != lastarg.SessionID) ||
+                        (x.AgentID != lastarg.AgentID)
+                       );
+                }
+                else
+                    update = true;
+
+                // These should be ordered from most-likely to
+                // least likely to change. I've made an initial
+                // guess at that.
+
+                if (update)
+                {
+                    AgentUpdateArgs arg = new AgentUpdateArgs();
+                    arg.AgentID = x.AgentID;
+                    arg.BodyRotation = x.BodyRotation;
+                    arg.CameraAtAxis = x.CameraAtAxis;
+                    arg.CameraCenter = x.CameraCenter;
+                    arg.CameraLeftAxis = x.CameraLeftAxis;
+                    arg.CameraUpAxis = x.CameraUpAxis;
+                    arg.ControlFlags = x.ControlFlags;
+                    arg.Far = x.Far;
+                    arg.Flags = x.Flags;
+                    arg.HeadRotation = x.HeadRotation;
+                    arg.SessionID = x.SessionID;
+                    arg.State = x.State;
+                    UpdateAgent handlerAgentUpdate = OnAgentUpdate;
+                    lastarg = arg; // save this set of arguments for nexttime
+                    if (handlerAgentUpdate != null)
+                        OnAgentUpdate(this, arg);
+
+                    handlerAgentUpdate = null;
+                }
+            }
+
+            return true;
+        }
+
         private bool HandleMoneyTransferRequest(IClientAPI sender, Packet Pack)
         {
             MoneyTransferRequestPacket money = (MoneyTransferRequestPacket)Pack;
@@ -5631,77 +5701,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 
                     break;
 
-                case PacketType.AgentUpdate:
-                    if (OnAgentUpdate != null)
-                    {
-                        bool update = false;
-                        AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack;
-
-                        #region Packet Session and User Check
-                        if (m_checkPackets)
-                        {
-                            if (agenUpdate.AgentData.SessionID != SessionId ||
-                                agenUpdate.AgentData.AgentID != AgentId)
-                                break;
-                        }
-                        #endregion
-
-                        AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData;
-
-                        // We can only check when we have something to check
-                        // against.
-
-                        if (lastarg != null)
-                        {
-                            update =
-                               (
-                                (x.BodyRotation != lastarg.BodyRotation) ||
-                                (x.CameraAtAxis != lastarg.CameraAtAxis) ||
-                                (x.CameraCenter != lastarg.CameraCenter) ||
-                                (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
-                                (x.CameraUpAxis != lastarg.CameraUpAxis) ||
-                                (x.ControlFlags != lastarg.ControlFlags) ||
-                                (x.Far != lastarg.Far) ||
-                                (x.Flags != lastarg.Flags) ||
-                                (x.State != lastarg.State) ||
-                                (x.HeadRotation != lastarg.HeadRotation) ||
-                                (x.SessionID != lastarg.SessionID) ||
-                                (x.AgentID != lastarg.AgentID)
-                               );
-                        }
-                        else
-                            update = true;
-
-                        // These should be ordered from most-likely to
-                        // least likely to change. I've made an initial
-                        // guess at that.
-
-                        if (update)
-                        {
-                            AgentUpdateArgs arg = new AgentUpdateArgs();
-                            arg.AgentID = x.AgentID;
-                            arg.BodyRotation = x.BodyRotation;
-                            arg.CameraAtAxis = x.CameraAtAxis;
-                            arg.CameraCenter = x.CameraCenter;
-                            arg.CameraLeftAxis = x.CameraLeftAxis;
-                            arg.CameraUpAxis = x.CameraUpAxis;
-                            arg.ControlFlags = x.ControlFlags;
-                            arg.Far = x.Far;
-                            arg.Flags = x.Flags;
-                            arg.HeadRotation = x.HeadRotation;
-                            arg.SessionID = x.SessionID;
-                            arg.State = x.State;
-                            UpdateAgent handlerAgentUpdate = OnAgentUpdate;
-                            lastarg = arg; // save this set of arguments for nexttime
-                            if (handlerAgentUpdate != null)
-                                OnAgentUpdate(this, arg);
-
-                            handlerAgentUpdate = null;
-                        }
-
-                    }
-                    break;
-
                 case PacketType.AgentAnimation:
                     AgentAnimationPacket AgentAni = (AgentAnimationPacket)Pack;
 
diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
index 9387bce..61b6d65 100644
--- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
@@ -96,12 +96,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
             else
             {
                 bool foundResult = false;
-                string resultstring = "";
-                List<ScenePresence> allav = DeadAvatar.Scene.GetScenePresences();
+                string resultstring = String.Empty;
+                ScenePresence[] allav = DeadAvatar.Scene.GetScenePresences();
                 try
                 {
-                    foreach (ScenePresence av in allav)
+                    for (int i = 0; i < allav.Length; i++)
                     {
+                        ScenePresence av = allav[i];
+
                         if (av.LocalId == killerObjectLocalID)
                         {
                             av.ControllingClient.SendAlertMessage("You fragged " + DeadAvatar.Firstname + " " + DeadAvatar.Lastname);
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index ebebaf9..72ec869 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -85,10 +85,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
         
         public void SendAlertToUser(string firstName, string lastName, string message, bool modal)
         {
-            List<ScenePresence> presenceList = m_scene.GetScenePresences();
+            ScenePresence[] presenceList = m_scene.GetScenePresences();
 
-            foreach (ScenePresence presence in presenceList)
+            for (int i = 0; i < presenceList.Length; i++)
             {
+                ScenePresence presence = presenceList[i];
+
                 if (presence.Firstname == firstName && presence.Lastname == lastName)
                 {
                     presence.ControllingClient.SendAgentAlertMessage(message, modal);
@@ -99,10 +101,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
         
         public void SendGeneralAlert(string message)
         {
-            List<ScenePresence> presenceList = m_scene.GetScenePresences();
+            ScenePresence[] presenceList = m_scene.GetScenePresences();
 
-            foreach (ScenePresence presence in presenceList)
+            for (int i = 0; i < presenceList.Length; i++)
             {
+                ScenePresence presence = presenceList[i];
+
                 if (!presence.IsChildAgent)
                     presence.ControllingClient.SendAlertMessage(message);
             }
@@ -150,10 +154,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
         public void SendNotificationToUsersInRegion(
             UUID fromAvatarID, string fromAvatarName, string message)
         {
-            List<ScenePresence> presenceList = m_scene.GetScenePresences();
+            ScenePresence[] presences = m_scene.GetScenePresences();
 
-            foreach (ScenePresence presence in presenceList)
+            for (int i = 0; i < presences.Length; i++)
             {
+                ScenePresence presence = presences[i];
                 if (!presence.IsChildAgent)
                     presence.ControllingClient.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message);
             }
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 3bb162e..e3a395e 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -414,9 +414,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
         private void handleEstateTeleportAllUsersHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID)
         {
             // Get a fresh list that will not change as people get teleported away
-            List<ScenePresence> prescences = m_scene.GetScenePresences(); 
-            foreach (ScenePresence p in prescences)
+            ScenePresence[] presences = m_scene.GetScenePresences();
+
+            for (int i = 0; i < presences.Length; i++)
             {
+                ScenePresence p = presences[i];
+
                 if (p.UUID != senderID)
                 {
                     // make sure they are still there, we could be working down a long list
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 4b87f92..d5e3445 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -253,7 +253,7 @@ namespace OpenSim.Region.Framework.Scenes
         protected int m_fps = 10;
         protected int m_frame = 0;
         protected float m_timespan = 0.089f;
-        protected DateTime m_lastupdate = DateTime.Now;
+        protected DateTime m_lastupdate = DateTime.UtcNow;
 
         private int m_update_physics = 1;
         private int m_update_entitymovement = 1;
@@ -1014,7 +1014,7 @@ namespace OpenSim.Region.Framework.Scenes
 //#endif
                 maintc = Environment.TickCount;
 
-                TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate;
+                TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
                 float physicsFPS = 0;
 
                 frameMS = Environment.TickCount;
@@ -1137,7 +1137,7 @@ namespace OpenSim.Region.Framework.Scenes
                     }
                     m_timedilation = tmpval;
 
-                    m_lastupdate = DateTime.Now;
+                    m_lastupdate = DateTime.UtcNow;
                 }
                 maintc = Environment.TickCount - maintc;
                 maintc = (int)(m_timespan * 1000) - maintc;
@@ -3496,9 +3496,7 @@ namespace OpenSim.Region.Framework.Scenes
         public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying)
         {
             ScenePresence presence;
-
-            lock (m_sceneGraph.ScenePresences)
-                m_sceneGraph.ScenePresences.TryGetValue(agentID, out presence);
+            m_sceneGraph.TryGetAvatar(agentID, out presence);
 
             if (presence != null)
             {
@@ -3709,8 +3707,7 @@ namespace OpenSim.Region.Framework.Scenes
                                             Vector3 lookAt, uint teleportFlags)
         {
             ScenePresence sp;
-            lock (m_sceneGraph.ScenePresences)
-                m_sceneGraph.ScenePresences.TryGetValue(remoteClient.AgentId, out sp);
+            m_sceneGraph.TryGetAvatar(remoteClient.AgentId, out sp);
 
             if (sp != null)
             {
@@ -4112,7 +4109,7 @@ namespace OpenSim.Region.Framework.Scenes
         /// This list is a new object, so it can be iterated over without locking.
         /// </summary>
         /// <returns></returns>
-        public List<ScenePresence> GetScenePresences()
+        public ScenePresence[] GetScenePresences()
         {
             return m_sceneGraph.GetScenePresences();
         }
@@ -4159,15 +4156,13 @@ namespace OpenSim.Region.Framework.Scenes
         public void ForEachScenePresence(Action<ScenePresence> action)
         {
             // We don't want to try to send messages if there are no avatars.
-            if (m_sceneGraph != null && m_sceneGraph.ScenePresences != null)
+            if (m_sceneGraph != null)
             {
                 try
                 {
-                    List<ScenePresence> presenceList = GetScenePresences();
-                    foreach (ScenePresence presence in presenceList)
-                    {
-                        action(presence);
-                    }
+                    ScenePresence[] presences = GetScenePresences();
+                    for (int i = 0; i < presences.Length; i++)
+                        action(presences[i]);
                 }
                 catch (Exception e)
                 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index deee6c3..db055f9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -66,7 +66,9 @@ namespace OpenSim.Region.Framework.Scenes
 
         #region Fields
 
-        protected internal Dictionary<UUID, ScenePresence> ScenePresences = new Dictionary<UUID, ScenePresence>();
+        protected Dictionary<UUID, ScenePresence> m_scenePresences = new Dictionary<UUID, ScenePresence>();
+        protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0];
+
         // SceneObjects is not currently populated or used.
         //public Dictionary<UUID, SceneObjectGroup> SceneObjects;
         protected internal EntityManager Entities = new EntityManager();
@@ -126,10 +128,12 @@ namespace OpenSim.Region.Framework.Scenes
 
         protected internal void Close()
         {
-            lock (ScenePresences)
+            lock (m_scenePresences)
             {
-                ScenePresences.Clear();
+                m_scenePresences.Clear();
+                m_scenePresenceArray = new ScenePresence[0];
             }
+
             lock (m_dictionary_lock)
             {
                 SceneObjectGroupsByFullID.Clear();
@@ -157,11 +161,9 @@ namespace OpenSim.Region.Framework.Scenes
 
         protected internal void UpdatePresences()
         {
-            List<ScenePresence> updateScenePresences = GetScenePresences();
-            foreach (ScenePresence pres in updateScenePresences)
-            {
-                pres.Update();
-            }
+            ScenePresence[] updateScenePresences = GetScenePresences();
+            for (int i = 0; i < updateScenePresences.Length; i++)
+                updateScenePresences[i].Update();
         }
 
         protected internal float UpdatePhysics(double elapsed)
@@ -190,15 +192,9 @@ namespace OpenSim.Region.Framework.Scenes
 
         protected internal void UpdateScenePresenceMovement()
         {
-            List<ScenePresence> moveEntities = GetScenePresences();
-
-            foreach (EntityBase entity in moveEntities)
-            {
-                //cfk. This throws occaisional exceptions on a heavily used region
-                //and I added this null check to try to preclude the exception.
-                if (entity != null)
-                    entity.UpdateMovement();
-            }
+            ScenePresence[] moveEntities = GetScenePresences();
+            for (int i = 0; i < moveEntities.Length; i++)
+                moveEntities[i].UpdateMovement();
         }
 
         #endregion
@@ -645,9 +641,34 @@ namespace OpenSim.Region.Framework.Scenes
 
             Entities[presence.UUID] = presence;
 
-            lock (ScenePresences)
+            lock (m_scenePresences)
             {
-                ScenePresences[presence.UUID] = presence;
+                if (!m_scenePresences.ContainsKey(presence.UUID))
+                {
+                    m_scenePresences.Add(presence.UUID, presence);
+
+                    // Create a new array of ScenePresence references
+                    int oldLength = m_scenePresenceArray.Length;
+                    ScenePresence[] newArray = new ScenePresence[oldLength + 1];
+                    Array.Copy(m_scenePresenceArray, newArray, oldLength);
+                    newArray[oldLength] = presence;
+                    m_scenePresenceArray = newArray;
+                }
+                else
+                {
+                    m_scenePresences[presence.UUID] = presence;
+                    
+                    // Do a linear search through the array of ScenePresence references
+                    // and update the modified entry
+                    for (int i = 0; i < m_scenePresenceArray.Length; i++)
+                    {
+                        if (m_scenePresenceArray[i].UUID == presence.UUID)
+                        {
+                            m_scenePresenceArray[i] = presence;
+                            break;
+                        }
+                    }
+                }
             }
         }
 
@@ -663,16 +684,30 @@ namespace OpenSim.Region.Framework.Scenes
                     agentID);
             }
 
-            lock (ScenePresences)
+            lock (m_scenePresences)
             {
-                if (!ScenePresences.Remove(agentID))
+                if (m_scenePresences.Remove(agentID))
+                {
+                    // Copy all of the elements from the previous array
+                    // into the new array except the removed element
+                    int oldLength = m_scenePresenceArray.Length;
+                    ScenePresence[] newArray = new ScenePresence[oldLength - 1];
+                    int j = 0;
+                    for (int i = 0; i < m_scenePresenceArray.Length; i++)
+                    {
+                        ScenePresence presence = m_scenePresenceArray[i];
+                        if (presence.UUID != agentID)
+                        {
+                            newArray[j] = presence;
+                            ++j;
+                        }
+                    }
+                    m_scenePresenceArray = newArray;
+                }
+                else
                 {
                     m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
                 }
-//                else
-//                {
-//                    m_log.InfoFormat("[SCENE] Removed scene presence {0} from scene presences list", agentID);
-//                }
             }
         }
 
@@ -704,20 +739,21 @@ namespace OpenSim.Region.Framework.Scenes
 
         public void RecalculateStats()
         {
-            List<ScenePresence> SPList = GetScenePresences();
+            ScenePresence[] presences = GetScenePresences();
             int rootcount = 0;
             int childcount = 0;
 
-            foreach (ScenePresence user in SPList)
+            for (int i = 0; i < presences.Length; i++)
             {
+                ScenePresence user = presences[i];
                 if (user.IsChildAgent)
-                    childcount++;
+                    ++childcount;
                 else
-                    rootcount++;
+                    ++rootcount;
             }
+
             m_numRootAgents = rootcount;
             m_numChildAgents = childcount;
-            
         }
 
         public int GetChildAgentCount()
@@ -767,12 +803,9 @@ namespace OpenSim.Region.Framework.Scenes
         /// locking is required to iterate over it.
         /// </summary>
         /// <returns></returns>
-        protected internal List<ScenePresence> GetScenePresences()
+        protected internal ScenePresence[] GetScenePresences()
         {
-            lock (ScenePresences)
-            {
-                return new List<ScenePresence>(ScenePresences.Values);
-            }
+            return m_scenePresenceArray;
         }
 
         protected internal List<ScenePresence> GetAvatars()
@@ -817,14 +850,13 @@ namespace OpenSim.Region.Framework.Scenes
             // No locking of scene presences here since we're passing back a list...
 
             List<ScenePresence> result = new List<ScenePresence>();
-            List<ScenePresence> ScenePresencesList = GetScenePresences();
+            ScenePresence[] scenePresences = GetScenePresences();
 
-            foreach (ScenePresence avatar in ScenePresencesList)
+            for (int i = 0; i < scenePresences.Length; i++)
             {
+                ScenePresence avatar = scenePresences[i];
                 if (filter(avatar))
-                {
                     result.Add(avatar);
-                }
             }
 
             return result;
@@ -839,9 +871,9 @@ namespace OpenSim.Region.Framework.Scenes
         {
             ScenePresence sp;
             
-            lock (ScenePresences)
+            lock (m_scenePresences)
             {
-                ScenePresences.TryGetValue(agentID, out sp);
+                m_scenePresences.TryGetValue(agentID, out sp);
             }
 
             return sp;
@@ -1000,48 +1032,24 @@ namespace OpenSim.Region.Framework.Scenes
 
         protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
         {
-            ScenePresence presence;
-            
-            lock (ScenePresences)
-            {
-                if (ScenePresences.TryGetValue(avatarId, out presence))
-                {
-                    avatar = presence;
-                    return true;
-
-                    //if (!presence.IsChildAgent)
-                    //{
-                    //    avatar = presence;
-                    //    return true;
-                    //}
-                    //else
-                    //{
-                    //    m_log.WarnFormat(
-                    //        "[INNER SCENE]: Requested avatar {0} could not be found in scene {1} since it is only registered as a child agent!",
-                    //        avatarId, m_parentScene.RegionInfo.RegionName);
-                    //}
-                }
-            }
-
-            avatar = null;
-            return false;
+            lock (m_scenePresences)
+                return m_scenePresences.TryGetValue(avatarId, out avatar);
         }
 
         protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
         {
-            lock (ScenePresences)
+            ScenePresence[] presences = GetScenePresences();
+
+            for (int i = 0; i < presences.Length; i++)
             {
-                foreach (ScenePresence presence in ScenePresences.Values)
+                ScenePresence presence = presences[i];
+
+                if (!presence.IsChildAgent)
                 {
-                    if (!presence.IsChildAgent)
+                    if (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0)
                     {
-                        string name = presence.ControllingClient.Name;
-
-                        if (String.Compare(avatarName, name, true) == 0)
-                        {
-                            avatar = presence;
-                            return true;
-                        }
+                        avatar = presence;
+                        return true;
                     }
                 }
             }
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index 3097929..dfaa7ea 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -411,41 +411,46 @@ namespace OpenSim.Region.Framework.Scenes
         /// <param name="newDebug"></param>
         public void SetDebugPacketLevelOnCurrentScene(int newDebug)
         {
-            ForEachCurrentScene(delegate(Scene scene)
-                                {
-                                    List<ScenePresence> scenePresences = scene.GetScenePresences();
+            ForEachCurrentScene(
+                delegate(Scene scene)
+                {
+                    ScenePresence[] scenePresences = scene.GetScenePresences();
+
+                    for (int i = 0; i < scenePresences.Length; i++)
+                    {
+                        ScenePresence scenePresence = scenePresences[i];
 
-                                    foreach (ScenePresence scenePresence in scenePresences)
-                                    {
-                                        if (!scenePresence.IsChildAgent)
-                                        {
-                                            m_log.ErrorFormat("Packet debug for {0} {1} set to {2}",
-                                                              scenePresence.Firstname,
-                                                              scenePresence.Lastname,
-                                                              newDebug);
+                        if (!scenePresence.IsChildAgent)
+                        {
+                            m_log.ErrorFormat("Packet debug for {0} {1} set to {2}",
+                                              scenePresence.Firstname,
+                                              scenePresence.Lastname,
+                                              newDebug);
 
-                                            scenePresence.ControllingClient.SetDebugPacketLevel(newDebug);
-                                        }
-                                    }
-                                });
+                            scenePresence.ControllingClient.SetDebugPacketLevel(newDebug);
+                        }
+                    }
+                }
+            );
         }
 
         public List<ScenePresence> GetCurrentSceneAvatars()
         {
             List<ScenePresence> avatars = new List<ScenePresence>();
 
-            ForEachCurrentScene(delegate(Scene scene)
-            {
-                List<ScenePresence> scenePresences = scene.GetScenePresences();
-
-                foreach (ScenePresence scenePresence in scenePresences)
+            ForEachCurrentScene(
+                delegate(Scene scene)
                 {
-                    if (!scenePresence.IsChildAgent)
+                    ScenePresence[] scenePresences = scene.GetScenePresences();
+
+                    for (int i = 0; i < scenePresences.Length; i++)
                     {
-                        avatars.Add(scenePresence);
+                        ScenePresence scenePresence = scenePresences[i];
+                        if (!scenePresence.IsChildAgent)
+                            avatars.Add(scenePresence);
                     }
                 }
-            });
+            );
 
             return avatars;
         }
@@ -456,7 +461,7 @@ namespace OpenSim.Region.Framework.Scenes
 
             ForEachCurrentScene(delegate(Scene scene)
             {
-                List<ScenePresence> scenePresences = scene.GetScenePresences();
+                ScenePresence[] scenePresences = scene.GetScenePresences();
                 presences.AddRange(scenePresences);
             });
 
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 69b3ded..4f19761 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1182,8 +1182,8 @@ namespace OpenSim.Region.Framework.Scenes
                 {
 //                    part.Inventory.RemoveScriptInstances();
 
-                    List<ScenePresence> avatars = Scene.GetScenePresences();
-                    for (int i = 0; i < avatars.Count; i++)
+                    ScenePresence[] avatars = Scene.GetScenePresences();
+                    for (int i = 0; i < avatars.Length; i++)
                     {
                         if (avatars[i].ParentID == LocalId)
                         {
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 32171a0..7193002 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1077,8 +1077,8 @@ if (m_shape != null) {
 
         private void SendObjectPropertiesToClient(UUID AgentID)
         {
-            List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences();
-            for (int i = 0; i < avatars.Count; i++)
+            ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
+            for (int i = 0; i < avatars.Length; i++)
             {
                 // Ugly reference :(
                 if (avatars[i].UUID == AgentID)
@@ -1140,8 +1140,8 @@ if (m_shape != null) {
         /// </summary>
         public void AddFullUpdateToAllAvatars()
         {
-            List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences();
-            for (int i = 0; i < avatars.Count; i++)
+            ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
+            for (int i = 0; i < avatars.Length; i++)
             {
                 avatars[i].SceneViewer.QueuePartForUpdate(this);
             }
@@ -1165,8 +1165,8 @@ if (m_shape != null) {
         /// Terse updates
         public void AddTerseUpdateToAllAvatars()
         {
-            List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences();
-            for (int i = 0; i < avatars.Count; i++)
+            ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
+            for (int i = 0; i < avatars.Length; i++)
             {
                 avatars[i].SceneViewer.QueuePartForUpdate(this);
             }
@@ -1894,24 +1894,24 @@ if (m_shape != null) {
                         }
                         else
                         {
-                            List<ScenePresence> avlist = m_parentGroup.Scene.GetScenePresences();
-                            if (avlist != null)
+                            ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences();
+
+                            for (int i = 0; i < avlist.Length; i++)
                             {
-                                foreach (ScenePresence av in avlist)
+                                ScenePresence av = avlist[i];
+
+                                if (av.LocalId == localId)
                                 {
-                                    if (av.LocalId == localId)
-                                    {
-                                        DetectedObject detobj = new DetectedObject();
-                                        detobj.keyUUID = av.UUID;
-                                        detobj.nameStr = av.ControllingClient.Name;
-                                        detobj.ownerUUID = av.UUID;
-                                        detobj.posVector = av.AbsolutePosition;
-                                        detobj.rotQuat = av.Rotation;
-                                        detobj.velVector = av.Velocity;
-                                        detobj.colliderType = 0;
-                                        detobj.groupUUID = av.ControllingClient.ActiveGroupId;
-                                        colliding.Add(detobj);
-                                    }
+                                    DetectedObject detobj = new DetectedObject();
+                                    detobj.keyUUID = av.UUID;
+                                    detobj.nameStr = av.ControllingClient.Name;
+                                    detobj.ownerUUID = av.UUID;
+                                    detobj.posVector = av.AbsolutePosition;
+                                    detobj.rotQuat = av.Rotation;
+                                    detobj.velVector = av.Velocity;
+                                    detobj.colliderType = 0;
+                                    detobj.groupUUID = av.ControllingClient.ActiveGroupId;
+                                    colliding.Add(detobj);
                                 }
                             }
                         }
@@ -1965,26 +1965,25 @@ if (m_shape != null) {
                         }
                         else
                         {
-                            List<ScenePresence> avlist = m_parentGroup.Scene.GetScenePresences();
-                            if (avlist != null)
+                            ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences();
+                            
+                            for (int i = 0; i < avlist.Length; i++)
                             {
-                                foreach (ScenePresence av in avlist)
+                                ScenePresence av = avlist[i];
+
+                                if (av.LocalId == localId)
                                 {
-                                    if (av.LocalId == localId)
-                                    {
-                                        DetectedObject detobj = new DetectedObject();
-                                        detobj.keyUUID = av.UUID;
-                                        detobj.nameStr = av.Name;
-                                        detobj.ownerUUID = av.UUID;
-                                        detobj.posVector = av.AbsolutePosition;
-                                        detobj.rotQuat = av.Rotation;
-                                        detobj.velVector = av.Velocity;
-                                        detobj.colliderType = 0;
-                                        detobj.groupUUID = av.ControllingClient.ActiveGroupId;
-                                        colliding.Add(detobj);
-                                    }
+                                    DetectedObject detobj = new DetectedObject();
+                                    detobj.keyUUID = av.UUID;
+                                    detobj.nameStr = av.Name;
+                                    detobj.ownerUUID = av.UUID;
+                                    detobj.posVector = av.AbsolutePosition;
+                                    detobj.rotQuat = av.Rotation;
+                                    detobj.velVector = av.Velocity;
+                                    detobj.colliderType = 0;
+                                    detobj.groupUUID = av.ControllingClient.ActiveGroupId;
+                                    colliding.Add(detobj);
                                 }
-
                             }
                         }
                     }
@@ -2035,24 +2034,24 @@ if (m_shape != null) {
                         }
                         else
                         {
-                            List<ScenePresence> avlist = m_parentGroup.Scene.GetScenePresences();
-                            if (avlist != null)
+                            ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences();
+
+                            for (int i = 0; i < avlist.Length; i++)
                             {
-                                foreach (ScenePresence av in avlist)
+                                ScenePresence av = avlist[i];
+
+                                if (av.LocalId == localId)
                                 {
-                                    if (av.LocalId == localId)
-                                    {
-                                        DetectedObject detobj = new DetectedObject();
-                                        detobj.keyUUID = av.UUID;
-                                        detobj.nameStr = av.Name;
-                                        detobj.ownerUUID = av.UUID;
-                                        detobj.posVector = av.AbsolutePosition;
-                                        detobj.rotQuat = av.Rotation;
-                                        detobj.velVector = av.Velocity;
-                                        detobj.colliderType = 0;
-                                        detobj.groupUUID = av.ControllingClient.ActiveGroupId;
-                                        colliding.Add(detobj);
-                                    }
+                                    DetectedObject detobj = new DetectedObject();
+                                    detobj.keyUUID = av.UUID;
+                                    detobj.nameStr = av.Name;
+                                    detobj.ownerUUID = av.UUID;
+                                    detobj.posVector = av.AbsolutePosition;
+                                    detobj.rotQuat = av.Rotation;
+                                    detobj.velVector = av.Velocity;
+                                    detobj.colliderType = 0;
+                                    detobj.groupUUID = av.ControllingClient.ActiveGroupId;
+                                    colliding.Add(detobj);
                                 }
                             }
                         }
@@ -2312,8 +2311,8 @@ if (m_shape != null) {
         /// </summary>
         public void SendFullUpdateToAllClients()
         {
-            List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences();
-            for (int i = 0; i < avatars.Count; i++)
+            ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
+            for (int i = 0; i < avatars.Length; i++)
             {
                 // Ugly reference :(
                 m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this,
@@ -2323,8 +2322,8 @@ if (m_shape != null) {
 
         public void SendFullUpdateToAllClientsExcept(UUID agentID)
         {
-            List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences();
-            for (int i = 0; i < avatars.Count; i++)
+            ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
+            for (int i = 0; i < avatars.Length; i++)
             {
                 // Ugly reference :(
                 if (avatars[i].UUID != agentID)
@@ -2467,8 +2466,8 @@ if (m_shape != null) {
         /// </summary>
         public void SendTerseUpdateToAllClients()
         {
-            List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences();
-            for (int i = 0; i < avatars.Count; i++)
+            ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
+            for (int i = 0; i < avatars.Length; i++)
             {
                 SendTerseUpdateToClient(avatars[i].ControllingClient);
             }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index ccfffe7..77706ac 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -869,14 +869,16 @@ namespace OpenSim.Region.Framework.Scenes
 
             m_isChildAgent = false;
 
-            List<ScenePresence> AnimAgents = m_scene.GetScenePresences();
-            foreach (ScenePresence p in AnimAgents)
+            ScenePresence[] animAgents = m_scene.GetScenePresences();
+            for (int i = 0; i < animAgents.Length; i++)
             {
-                if (p != this)
-                    p.SendAnimPackToClient(ControllingClient);
+                ScenePresence presence = animAgents[i];
+
+                if (presence != this)
+                    presence.SendAnimPackToClient(ControllingClient);
             }
-            m_scene.EventManager.TriggerOnMakeRootAgent(this);
 
+            m_scene.EventManager.TriggerOnMakeRootAgent(this);
         }
 
         /// <summary>
@@ -2533,9 +2535,12 @@ namespace OpenSim.Region.Framework.Scenes
         {
             m_perfMonMS = Environment.TickCount;
 
-            List<ScenePresence> avatars = m_scene.GetScenePresences();
-            foreach (ScenePresence avatar in avatars)
+            ScenePresence[] avatars = m_scene.GetScenePresences();
+
+            for (int i = 0; i < avatars.Length; i++)
             {
+                ScenePresence avatar = avatars[i];
+
                 // only send if this is the root (children are only "listening posts" in a foreign region)
                 if (!IsChildAgent)
                 {
@@ -2553,7 +2558,7 @@ namespace OpenSim.Region.Framework.Scenes
                 }
             }
 
-            m_scene.StatsReporter.AddAgentUpdates(avatars.Count);
+            m_scene.StatsReporter.AddAgentUpdates(avatars.Length);
             m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
 
             //SendAnimPack();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 669189d..56d4d28 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7227,13 +7227,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         public LSL_Integer llGetNumberOfPrims()
         {
             m_host.AddScriptLPS(1);
-            List<ScenePresence> presences = World.GetScenePresences();
-            if (presences.Count == 0)
+            ScenePresence[] presences = World.GetScenePresences();
+            if (presences.Length == 0)
                 return 0;
 
             int avatarCount = 0;
-            foreach (ScenePresence presence in presences)
+            for (int i = 0; i < presences.Length; i++)
             {
+                ScenePresence presence = presences[i];
+
                 if (!presence.IsChildAgent && presence.ParentID != 0)
                 {
                     if (m_host.ParentGroup.HasChildPrim(presence.ParentID))
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index a09c8db..ee01c3c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -404,7 +404,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
 
         private List<SensedEntity> doAgentSensor(SenseRepeatClass ts)
         {
-            List<ScenePresence> Presences;
+            List<ScenePresence> presences;
             List<SensedEntity> sensedEntities = new List<SensedEntity>();
 
             // If this is an avatar sense by key try to get them directly
@@ -414,16 +414,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
                 ScenePresence p = m_CmdManager.m_ScriptEngine.World.GetScenePresence(ts.keyID);
                 if (p == null)
                     return sensedEntities;
-                Presences = new List<ScenePresence>();
-                Presences.Add(p);
+                presences = new List<ScenePresence>();
+                presences.Add(p);
             }
             else
             {
-                Presences = m_CmdManager.m_ScriptEngine.World.GetScenePresences();
+                presences = new List<ScenePresence>(m_CmdManager.m_ScriptEngine.World.GetScenePresences());
             }
 
             // If nobody about quit fast
-            if (Presences.Count == 0)
+            if (presences.Count == 0)
                 return sensedEntities;
 
             SceneObjectPart SensePoint = ts.host;
@@ -440,8 +440,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
             Vector3 toRegionPos;
             double dis;
 
-            foreach (ScenePresence presence in Presences)
+            for (int i = 0; i < presences.Count; i++)
             {
+                ScenePresence presence = presences[i];
                 bool keep = true;
 
                 if (presence.IsDeleted)
diff --git a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs
index d7c39a3..704b74f 100644
--- a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs
+++ b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs
@@ -68,11 +68,11 @@ namespace OpenSim.Region.UserStatistics
             HTMLUtil.OL_O(ref output, "");
             foreach (Scene scene in all_scenes)
             {
-                List<ScenePresence> avatarInScene = scene.GetScenePresences();
+                ScenePresence[] avatarInScene = scene.GetScenePresences();
 
-                HTMLUtil.LI_O(ref output, "");
+                HTMLUtil.LI_O(ref output, String.Empty);
                 output.Append(scene.RegionInfo.RegionName);
-                HTMLUtil.OL_O(ref output, "");
+                HTMLUtil.OL_O(ref output, String.Empty);
                 foreach (ScenePresence av in avatarInScene)
                 {
                     Dictionary<string,string> queues = new Dictionary<string, string>();
@@ -81,7 +81,7 @@ namespace OpenSim.Region.UserStatistics
                         IStatsCollector isClient = (IStatsCollector) av.ControllingClient;
                         queues = decodeQueueReport(isClient.Report());
                     }
-                    HTMLUtil.LI_O(ref output, "");
+                    HTMLUtil.LI_O(ref output, String.Empty);
                     output.Append(av.Name);
                     output.Append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
                     output.Append((av.IsChildAgent ? "Child" : "Root"));
@@ -96,12 +96,12 @@ namespace OpenSim.Region.UserStatistics
                                                     (int) av.AbsolutePosition.Z));
                     }
                     Dictionary<string, int> throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1));
-                    
-                    HTMLUtil.UL_O(ref output, "");
+
+                    HTMLUtil.UL_O(ref output, String.Empty);
 
                     foreach (string throttlename in throttles.Keys)
                     {
-                        HTMLUtil.LI_O(ref output, "");
+                        HTMLUtil.LI_O(ref output, String.Empty);
                         output.Append(throttlename);
                         output.Append(":");
                         output.Append(throttles[throttlename].ToString());
-- 
cgit v1.1