mantis 8438: work around null ref

0.9.1.0-post-fixes
UbitUmarov 2019-01-01 13:16:35 +00:00
parent 02492f7b15
commit 9c043fe414
1 changed files with 26 additions and 27 deletions

View File

@ -69,7 +69,7 @@ namespace OpenSim.Region.Framework.Scenes
#region Fields #region Fields
protected System.Threading.ReaderWriterLockSlim m_scenePresencesLock = new System.Threading.ReaderWriterLockSlim(); protected System.Threading.ReaderWriterLockSlim m_scenePresencesLock;
protected ConcurrentDictionary<UUID, ScenePresence> m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>(); protected ConcurrentDictionary<UUID, ScenePresence> m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>();
protected ConcurrentDictionary<uint, ScenePresence> m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>(); protected ConcurrentDictionary<uint, ScenePresence> m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>();
@ -119,6 +119,7 @@ namespace OpenSim.Region.Framework.Scenes
protected internal SceneGraph(Scene parent) protected internal SceneGraph(Scene parent)
{ {
m_scenePresencesLock = new System.Threading.ReaderWriterLockSlim();
m_parentScene = parent; m_parentScene = parent;
} }
@ -153,6 +154,9 @@ namespace OpenSim.Region.Framework.Scenes
m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>(); m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>();
m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>(); m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>();
m_scenePresenceArray = new List<ScenePresence>(); m_scenePresenceArray = new List<ScenePresence>();
if (_PhyScene != null)
_PhyScene.OnPhysicsCrash -= physicsBasedCrash;
_PhyScene = null;
} }
finally finally
{ {
@ -168,6 +172,7 @@ namespace OpenSim.Region.Framework.Scenes
Entities.Clear(); Entities.Clear();
m_scenePresencesLock.Dispose(); m_scenePresencesLock.Dispose();
m_scenePresencesLock = null;
} }
#region Update Methods #region Update Methods
@ -695,10 +700,13 @@ namespace OpenSim.Region.Framework.Scenes
ScenePresence presence = new ScenePresence(client, m_parentScene, appearance, type); ScenePresence presence = new ScenePresence(client, m_parentScene, appearance, type);
Entities[presence.UUID] = presence; Entities[presence.UUID] = presence;
bool entered = false;
m_scenePresencesLock.EnterWriteLock();
try try
{ {
m_scenePresencesLock.EnterWriteLock();
entered = true;
m_numChildAgents++; m_numChildAgents++;
List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@ -731,7 +739,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
finally finally
{ {
m_scenePresencesLock.ExitWriteLock(); if(entered)
m_scenePresencesLock.ExitWriteLock();
} }
return presence; return presence;
@ -749,9 +758,11 @@ namespace OpenSim.Region.Framework.Scenes
agentID); agentID);
} }
m_scenePresencesLock.EnterWriteLock(); bool entered = false;
try try
{ {
m_scenePresencesLock.EnterWriteLock();
entered = true;
// Remove the presence reference from the dictionary // Remove the presence reference from the dictionary
ScenePresence oldref; ScenePresence oldref;
if(m_scenePresenceMap.TryRemove(agentID, out oldref)) if(m_scenePresenceMap.TryRemove(agentID, out oldref))
@ -769,7 +780,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
finally finally
{ {
m_scenePresencesLock.ExitWriteLock(); if(entered)
m_scenePresencesLock.ExitWriteLock();
} }
} }
@ -896,15 +908,21 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns></returns> /// <returns></returns>
protected internal List<ScenePresence> GetScenePresences() protected internal List<ScenePresence> GetScenePresences()
{ {
bool entered = false;
m_scenePresencesLock.EnterReadLock();
try try
{ {
m_scenePresencesLock.EnterReadLock();
entered = true;
return m_scenePresenceArray; return m_scenePresenceArray;
} }
catch
{
return new List<ScenePresence>();
}
finally finally
{ {
m_scenePresencesLock.ExitReadLock(); if(entered)
m_scenePresencesLock.ExitReadLock();
} }
} }
@ -1207,8 +1225,6 @@ namespace OpenSim.Region.Framework.Scenes
{ {
foreach (SceneObjectPart p in ((SceneObjectGroup)entity).Parts) foreach (SceneObjectPart p in ((SceneObjectGroup)entity).Parts)
{ {
// m_log.DebugFormat("[SCENE GRAPH]: Part {0} has name {1}", p.UUID, p.Name);
if (p.Name == name) if (p.Name == name)
{ {
sop = p; sop = p;
@ -1312,23 +1328,6 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="action"></param> /// <param name="action"></param>
public void ForEachScenePresence(Action<ScenePresence> action) public void ForEachScenePresence(Action<ScenePresence> action)
{ {
// Once all callers have their delegates configured for parallelism, we can unleash this
/*
Action<ScenePresence> protectedAction = new Action<ScenePresence>(delegate(ScenePresence sp)
{
try
{
action(sp);
}
catch (Exception e)
{
m_log.Info("[SCENEGRAPH]: Error in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
m_log.Info("[SCENEGRAPH]: Stack Trace: " + e.StackTrace);
}
});
Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction);
*/
// For now, perform actions serially
List<ScenePresence> presences = GetScenePresences(); List<ScenePresence> presences = GetScenePresences();
foreach (ScenePresence sp in presences) foreach (ScenePresence sp in presences)
{ {