change scenegraph locking

0.9.1.0-post-fixes
UbitUmarov 2019-01-06 01:44:37 +00:00
parent c5604d3857
commit 3e49e13249
1 changed files with 70 additions and 53 deletions

View File

@ -150,21 +150,28 @@ namespace OpenSim.Region.Framework.Scenes
protected internal void Close() protected internal void Close()
{ {
m_scenePresencesLock.EnterWriteLock(); bool entered = false;
try try
{ {
m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>(); try { }
m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>(); finally
m_scenePresenceArray = new List<ScenePresence>(); {
m_spArrayLastVersion = 0; m_scenePresencesLock.EnterWriteLock();
m_spArrayVersion = 0; entered = true;
if (_PhyScene != null) m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>();
_PhyScene.OnPhysicsCrash -= physicsBasedCrash; m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>();
_PhyScene = null; m_scenePresenceArray = new List<ScenePresence>();
m_spArrayLastVersion = 0;
m_spArrayVersion = 0;
if (_PhyScene != null)
_PhyScene.OnPhysicsCrash -= physicsBasedCrash;
_PhyScene = null;
}
} }
finally finally
{ {
m_scenePresencesLock.ExitWriteLock(); if(entered)
m_scenePresencesLock.ExitWriteLock();
} }
lock (SceneObjectGroupsByFullID) lock (SceneObjectGroupsByFullID)
@ -708,32 +715,36 @@ namespace OpenSim.Region.Framework.Scenes
try try
{ {
m_scenePresencesLock.EnterWriteLock(); try{ }
entered = true; finally
m_numChildAgents++;
if (!m_scenePresenceMap.ContainsKey(presence.UUID))
{ {
m_scenePresenceMap[presence.UUID] = presence; m_scenePresencesLock.EnterWriteLock();
m_scenePresenceLocalIDMap[presence.LocalId] = presence; entered = true;
}
else m_numChildAgents++;
{
// Remember the old presence reference from the dictionary if (!m_scenePresenceMap.ContainsKey(presence.UUID))
ScenePresence oldref = m_scenePresenceMap[presence.UUID];
uint oldLocalID = oldref.LocalId;
// Replace the presence reference in the dictionary with the new value
m_scenePresenceMap[presence.UUID] = presence;
if(presence.LocalId != oldLocalID)
{ {
m_scenePresenceLocalIDMap.TryRemove(oldLocalID, out oldref); m_scenePresenceMap[presence.UUID] = presence;
m_scenePresenceLocalIDMap[presence.LocalId] = presence; m_scenePresenceLocalIDMap[presence.LocalId] = presence;
} }
// Find the index in the list where the old ref was stored and update the reference else
} {
// Remember the old presence reference from the dictionary
ScenePresence oldref = m_scenePresenceMap[presence.UUID];
uint oldLocalID = oldref.LocalId;
// Replace the presence reference in the dictionary with the new value
m_scenePresenceMap[presence.UUID] = presence;
if(presence.LocalId != oldLocalID)
{
m_scenePresenceLocalIDMap.TryRemove(oldLocalID, out oldref);
m_scenePresenceLocalIDMap[presence.LocalId] = presence;
}
// Find the index in the list where the old ref was stored and update the reference
}
++m_spArrayVersion; ++m_spArrayVersion;
}
} }
finally finally
{ {
@ -759,19 +770,23 @@ namespace OpenSim.Region.Framework.Scenes
bool entered = false; bool entered = false;
try try
{ {
m_scenePresencesLock.EnterWriteLock(); try { }
entered = true; finally
// Remove the presence reference from the dictionary
ScenePresence oldref;
if(m_scenePresenceMap.TryRemove(agentID, out oldref))
{ {
// Find the index in the list where the old ref was stored and remove the reference m_scenePresencesLock.EnterWriteLock();
m_scenePresenceLocalIDMap.TryRemove(oldref.LocalId, out oldref); entered = true;
++m_spArrayVersion; // Remove the presence reference from the dictionary
} ScenePresence oldref;
else if(m_scenePresenceMap.TryRemove(agentID, out oldref))
{ {
m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); // Find the index in the list where the old ref was stored and remove the reference
m_scenePresenceLocalIDMap.TryRemove(oldref.LocalId, out oldref);
++m_spArrayVersion;
}
else
{
m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
}
} }
} }
finally finally
@ -905,26 +920,28 @@ namespace OpenSim.Region.Framework.Scenes
protected internal List<ScenePresence> GetScenePresences() protected internal List<ScenePresence> GetScenePresences()
{ {
bool entered = false; bool entered = false;
List<ScenePresence> ret = new List<ScenePresence>();
try try
{ {
m_scenePresencesLock.EnterWriteLock(); try{ }
entered = true; finally
if(m_spArrayLastVersion != m_spArrayVersion)
{ {
m_scenePresenceArray = new List<ScenePresence>(m_scenePresenceMap.Values); m_scenePresencesLock.EnterWriteLock();
m_spArrayLastVersion = m_spArrayVersion; entered = true;
if(m_spArrayLastVersion != m_spArrayVersion)
{
m_scenePresenceArray = new List<ScenePresence>(m_scenePresenceMap.Values);
m_spArrayLastVersion = m_spArrayVersion;
}
ret = m_scenePresenceArray;
} }
return m_scenePresenceArray;
}
catch
{
return new List<ScenePresence>();
} }
finally finally
{ {
if(entered) if(entered)
m_scenePresencesLock.ExitWriteLock(); m_scenePresencesLock.ExitWriteLock();
} }
return ret;
} }
/// <summary> /// <summary>