From 14a86de115934e981e5c3e413821861434ccf5e8 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 10 May 2010 12:45:33 -0700 Subject: Fix another ReaderWriterLockSlim issue --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 62b44bd..c4cff12 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -840,12 +840,12 @@ namespace OpenSim.Region.Framework.Scenes } else { + m_items.LockItemsForRead(false); m_log.ErrorFormat( "[PRIM INVENTORY]: " + "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", itemID, m_part.Name, m_part.UUID); } - m_items.LockItemsForWrite(false); return -1; } -- cgit v1.1 From 7705012ee7b016f8e163c5e9586fef724b233932 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 12 May 2010 08:25:40 -0700 Subject: Optimise the heavily used GetScenePresences; eliminate the array->list conversion on every call and transition from hard locks to ReaderWriter locks. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 56 +++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index f43de20..c16ba12 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -70,6 +70,9 @@ namespace OpenSim.Region.Framework.Scenes protected Dictionary m_scenePresences = new Dictionary(); protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0]; + protected List m_scenePresenceList = new List(); + + protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim(); // SceneObjects is not currently populated or used. //public Dictionary SceneObjects; @@ -132,10 +135,16 @@ namespace OpenSim.Region.Framework.Scenes protected internal void Close() { - lock (m_scenePresences) + m_scenePresencesLock.EnterWriteLock(); + try { m_scenePresences.Clear(); m_scenePresenceArray = new ScenePresence[0]; + m_scenePresenceList = new List(); + } + finally + { + m_scenePresencesLock.ExitWriteLock(); } lock (m_dictionary_lock) @@ -542,7 +551,8 @@ namespace OpenSim.Region.Framework.Scenes Entities[presence.UUID] = presence; - lock (m_scenePresences) + m_scenePresencesLock.EnterWriteLock(); + try { if (!m_scenePresences.ContainsKey(presence.UUID)) { @@ -554,11 +564,12 @@ namespace OpenSim.Region.Framework.Scenes Array.Copy(m_scenePresenceArray, newArray, oldLength); newArray[oldLength] = presence; m_scenePresenceArray = newArray; + m_scenePresenceList = new List(m_scenePresenceArray); } 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++) @@ -569,8 +580,13 @@ namespace OpenSim.Region.Framework.Scenes break; } } + m_scenePresenceList = new List(m_scenePresenceArray); } } + finally + { + m_scenePresencesLock.ExitWriteLock(); + } } /// @@ -585,7 +601,8 @@ namespace OpenSim.Region.Framework.Scenes agentID); } - lock (m_scenePresences) + m_scenePresencesLock.EnterWriteLock(); + try { if (m_scenePresences.Remove(agentID)) { @@ -604,12 +621,17 @@ namespace OpenSim.Region.Framework.Scenes } } m_scenePresenceArray = newArray; + m_scenePresenceList = new List(m_scenePresenceArray); } else { m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); } } + finally + { + m_scenePresencesLock.ExitWriteLock(); + } } protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) @@ -730,8 +752,15 @@ namespace OpenSim.Region.Framework.Scenes /// private List GetScenePresences() { - lock (m_scenePresences) - return new List(m_scenePresenceArray); + m_scenePresencesLock.EnterReadLock(); + try + { + return m_scenePresenceList; + } + finally + { + m_scenePresencesLock.ExitReadLock(); + } } /// @@ -742,10 +771,15 @@ namespace OpenSim.Region.Framework.Scenes protected internal ScenePresence GetScenePresence(UUID agentID) { ScenePresence sp; - lock (m_scenePresences) + m_scenePresencesLock.EnterReadLock(); + try { m_scenePresences.TryGetValue(agentID, out sp); } + finally + { + m_scenePresencesLock.ExitReadLock(); + } return sp; } @@ -780,10 +814,15 @@ namespace OpenSim.Region.Framework.Scenes protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) { - lock (m_scenePresences) + m_scenePresencesLock.EnterReadLock(); + try { m_scenePresences.TryGetValue(agentID, out avatar); } + finally + { + m_scenePresencesLock.ExitReadLock(); + } return (avatar != null); } @@ -1061,6 +1100,7 @@ namespace OpenSim.Region.Framework.Scenes Parallel.ForEach(GetScenePresences(), protectedAction); */ // For now, perform actiona serially + foreach (ScenePresence sp in GetScenePresences()) { try -- cgit v1.1 From fd37a21b59836143f50fdf994c691d65bd641d52 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 12 May 2010 08:34:47 -0700 Subject: Kill some locks that have crept into SOG --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 35134d6..a4b8944 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3651,7 +3651,8 @@ namespace OpenSim.Region.Framework.Scenes if (atRotTargets.Count > 0) { uint[] localids = new uint[0]; - lock (m_parts) + lockPartsForRead(true); + try { localids = new uint[m_parts.Count]; int cntr = 0; @@ -3661,6 +3662,10 @@ namespace OpenSim.Region.Framework.Scenes cntr++; } } + finally + { + lockPartsForRead(false); + } for (int ctr = 0; ctr < localids.Length; ctr++) { @@ -3679,7 +3684,8 @@ namespace OpenSim.Region.Framework.Scenes { //trigger not_at_target uint[] localids = new uint[0]; - lock (m_parts) + lockPartsForRead(true); + try { localids = new uint[m_parts.Count]; int cntr = 0; @@ -3689,6 +3695,10 @@ namespace OpenSim.Region.Framework.Scenes cntr++; } } + finally + { + lockPartsForRead(false); + } for (int ctr = 0; ctr < localids.Length; ctr++) { -- cgit v1.1