mirror of
https://github.com/opensim/opensim.git
synced 2026-08-04 16:22:50 +08:00
First pass at cleaning up thread safety in EntityManager and SceneGraph
This commit is contained in:
@@ -348,68 +348,57 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
|
||||
return false;
|
||||
|
||||
lock (sceneObject)
|
||||
{
|
||||
if (Entities.ContainsKey(sceneObject.UUID))
|
||||
if (Entities.ContainsKey(sceneObject.UUID))
|
||||
return false;
|
||||
|
||||
// Clamp child prim sizes and add child prims to the m_numPrim count
|
||||
lock (sceneObject.Children)
|
||||
{
|
||||
if (m_parentScene.m_clampPrimSize)
|
||||
{
|
||||
// m_log.WarnFormat(
|
||||
// "[SCENE GRAPH]: Scene object {0} {1} was already in region {2} on add request",
|
||||
// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE GRAPH]: Adding object {0} {1} to region {2}",
|
||||
// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
|
||||
|
||||
lock (sceneObject.Children)
|
||||
{
|
||||
if (m_parentScene.m_clampPrimSize)
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
{
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
{
|
||||
Vector3 scale = part.Shape.Scale;
|
||||
|
||||
if (scale.X > m_parentScene.m_maxNonphys)
|
||||
scale.X = m_parentScene.m_maxNonphys;
|
||||
if (scale.Y > m_parentScene.m_maxNonphys)
|
||||
scale.Y = m_parentScene.m_maxNonphys;
|
||||
if (scale.Z > m_parentScene.m_maxNonphys)
|
||||
scale.Z = m_parentScene.m_maxNonphys;
|
||||
|
||||
part.Shape.Scale = scale;
|
||||
}
|
||||
Vector3 scale = part.Shape.Scale;
|
||||
|
||||
if (scale.X > m_parentScene.m_maxNonphys)
|
||||
scale.X = m_parentScene.m_maxNonphys;
|
||||
if (scale.Y > m_parentScene.m_maxNonphys)
|
||||
scale.Y = m_parentScene.m_maxNonphys;
|
||||
if (scale.Z > m_parentScene.m_maxNonphys)
|
||||
scale.Z = m_parentScene.m_maxNonphys;
|
||||
|
||||
part.Shape.Scale = scale;
|
||||
}
|
||||
|
||||
m_numPrim += sceneObject.Children.Count;
|
||||
}
|
||||
|
||||
sceneObject.AttachToScene(m_parentScene);
|
||||
|
||||
if (sendClientUpdates)
|
||||
sceneObject.ScheduleGroupForFullUpdate();
|
||||
|
||||
Entities.Add(sceneObject);
|
||||
m_numPrim += sceneObject.Children.Count;
|
||||
}
|
||||
|
||||
if (attachToBackup)
|
||||
sceneObject.AttachToBackup();
|
||||
sceneObject.AttachToScene(m_parentScene);
|
||||
|
||||
if (OnObjectCreate != null)
|
||||
OnObjectCreate(sceneObject);
|
||||
|
||||
lock (SceneObjectGroupsByFullID)
|
||||
{
|
||||
SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
SceneObjectGroupsByFullID[part.UUID] = sceneObject;
|
||||
}
|
||||
|
||||
lock (SceneObjectGroupsByLocalID)
|
||||
{
|
||||
SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
|
||||
}
|
||||
if (sendClientUpdates)
|
||||
sceneObject.ScheduleGroupForFullUpdate();
|
||||
|
||||
Entities.Add(sceneObject);
|
||||
|
||||
if (attachToBackup)
|
||||
sceneObject.AttachToBackup();
|
||||
|
||||
if (OnObjectCreate != null)
|
||||
OnObjectCreate(sceneObject);
|
||||
|
||||
lock (SceneObjectGroupsByFullID)
|
||||
{
|
||||
SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
SceneObjectGroupsByFullID[part.UUID] = sceneObject;
|
||||
}
|
||||
|
||||
lock (SceneObjectGroupsByLocalID)
|
||||
{
|
||||
SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -421,42 +410,38 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <returns>true if the object was deleted, false if there was no object to delete</returns>
|
||||
public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked)
|
||||
{
|
||||
if (Entities.ContainsKey(uuid))
|
||||
EntityBase entity;
|
||||
if (!Entities.TryGetValue(uuid, out entity) && entity is SceneObjectGroup)
|
||||
return false;
|
||||
|
||||
SceneObjectGroup grp = (SceneObjectGroup)entity;
|
||||
|
||||
if (!resultOfObjectLinked)
|
||||
{
|
||||
SceneObjectGroup grp = (SceneObjectGroup)Entities[uuid];
|
||||
m_numPrim -= grp.PrimCount;
|
||||
|
||||
if (!resultOfObjectLinked)
|
||||
{
|
||||
m_numPrim -= grp.PrimCount;
|
||||
|
||||
if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
|
||||
RemovePhysicalPrim(grp.PrimCount);
|
||||
}
|
||||
|
||||
if (OnObjectRemove != null)
|
||||
OnObjectRemove(Entities[uuid]);
|
||||
|
||||
lock (SceneObjectGroupsByFullID)
|
||||
{
|
||||
foreach (SceneObjectPart part in grp.Children.Values)
|
||||
SceneObjectGroupsByFullID.Remove(part.UUID);
|
||||
SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID);
|
||||
}
|
||||
lock (SceneObjectGroupsByLocalID)
|
||||
{
|
||||
foreach (SceneObjectPart part in grp.Children.Values)
|
||||
SceneObjectGroupsByLocalID.Remove(part.LocalId);
|
||||
SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId);
|
||||
}
|
||||
|
||||
Entities.Remove(uuid);
|
||||
//SceneObjectGroup part;
|
||||
//((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
|
||||
|
||||
return true;
|
||||
if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
|
||||
RemovePhysicalPrim(grp.PrimCount);
|
||||
}
|
||||
|
||||
return false;
|
||||
if (OnObjectRemove != null)
|
||||
OnObjectRemove(Entities[uuid]);
|
||||
|
||||
lock (SceneObjectGroupsByFullID)
|
||||
{
|
||||
foreach (SceneObjectPart part in grp.Children.Values)
|
||||
SceneObjectGroupsByFullID.Remove(part.UUID);
|
||||
SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID);
|
||||
}
|
||||
|
||||
lock (SceneObjectGroupsByLocalID)
|
||||
{
|
||||
foreach (SceneObjectPart part in grp.Children.Values)
|
||||
SceneObjectGroupsByLocalID.Remove(part.LocalId);
|
||||
SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId);
|
||||
}
|
||||
|
||||
return Entities.Remove(uuid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -468,9 +453,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
protected internal void AddToUpdateList(SceneObjectGroup obj)
|
||||
{
|
||||
lock (m_updateList)
|
||||
{
|
||||
m_updateList[obj.UUID] = obj;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -480,34 +463,39 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
if (!Monitor.TryEnter(m_updateLock))
|
||||
return;
|
||||
|
||||
List<SceneObjectGroup> updates;
|
||||
|
||||
// Some updates add more updates to the updateList.
|
||||
// Get the current list of updates and clear the list before iterating
|
||||
lock (m_updateList)
|
||||
try
|
||||
{
|
||||
updates = new List<SceneObjectGroup>(m_updateList.Values);
|
||||
m_updateList.Clear();
|
||||
}
|
||||
List<SceneObjectGroup> updates;
|
||||
|
||||
// Go through all updates
|
||||
for (int i = 0; i < updates.Count; i++)
|
||||
{
|
||||
SceneObjectGroup sog = updates[i];
|
||||
|
||||
// Don't abort the whole update if one entity happens to give us an exception.
|
||||
try
|
||||
// Some updates add more updates to the updateList.
|
||||
// Get the current list of updates and clear the list before iterating
|
||||
lock (m_updateList)
|
||||
{
|
||||
sog.Update();
|
||||
updates = new List<SceneObjectGroup>(m_updateList.Values);
|
||||
m_updateList.Clear();
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
// Go through all updates
|
||||
for (int i = 0; i < updates.Count; i++)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
|
||||
SceneObjectGroup sog = updates[i];
|
||||
|
||||
// Don't abort the whole update if one entity happens to give us an exception.
|
||||
try
|
||||
{
|
||||
sog.Update();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Monitor.Exit(m_updateLock);
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(m_updateLock);
|
||||
}
|
||||
}
|
||||
|
||||
protected internal void AddPhysicalPrim(int number)
|
||||
@@ -864,8 +852,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <returns>null if no scene object group containing that prim is found</returns>
|
||||
public SceneObjectGroup GetGroupByPrim(uint localID)
|
||||
{
|
||||
if (Entities.ContainsKey(localID))
|
||||
return Entities[localID] as SceneObjectGroup;
|
||||
EntityBase entity;
|
||||
if (Entities.TryGetValue(localID, out entity))
|
||||
return entity as SceneObjectGroup;
|
||||
|
||||
//m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID);
|
||||
SceneObjectGroup sog;
|
||||
@@ -879,23 +868,22 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
List<EntityBase> EntityList = GetEntities();
|
||||
foreach (EntityBase ent in EntityList)
|
||||
EntityBase[] entityList = GetEntities();
|
||||
foreach (EntityBase ent in entityList)
|
||||
{
|
||||
//m_log.DebugFormat("Looking at entity {0}", ent.UUID);
|
||||
if (ent is SceneObjectGroup)
|
||||
{
|
||||
if (((SceneObjectGroup)ent).HasChildPrim(localID))
|
||||
sog = (SceneObjectGroup)ent;
|
||||
if (sog.HasChildPrim(localID))
|
||||
{
|
||||
sog = (SceneObjectGroup)ent;
|
||||
lock (SceneObjectGroupsByLocalID)
|
||||
{
|
||||
SceneObjectGroupsByLocalID[localID] = sog;
|
||||
}
|
||||
return sog;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -921,23 +909,21 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
List<EntityBase> EntityList = GetEntities();
|
||||
|
||||
foreach (EntityBase ent in EntityList)
|
||||
EntityBase[] entityList = GetEntities();
|
||||
foreach (EntityBase ent in entityList)
|
||||
{
|
||||
if (ent is SceneObjectGroup)
|
||||
{
|
||||
if (((SceneObjectGroup)ent).HasChildPrim(fullID))
|
||||
sog = (SceneObjectGroup)ent;
|
||||
if (sog.HasChildPrim(fullID))
|
||||
{
|
||||
sog = (SceneObjectGroup)ent;
|
||||
lock (SceneObjectGroupsByFullID)
|
||||
{
|
||||
SceneObjectGroupsByFullID[fullID] = sog;
|
||||
}
|
||||
return sog;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -946,7 +932,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// Primitive Ray Tracing
|
||||
float closestDistance = 280f;
|
||||
EntityIntersection result = new EntityIntersection();
|
||||
List<EntityBase> EntityList = GetEntities();
|
||||
EntityBase[] EntityList = GetEntities();
|
||||
foreach (EntityBase ent in EntityList)
|
||||
{
|
||||
if (ent is SceneObjectGroup)
|
||||
@@ -984,23 +970,28 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <returns>null if the part was not found</returns>
|
||||
protected internal SceneObjectPart GetSceneObjectPart(string name)
|
||||
{
|
||||
List<EntityBase> EntityList = GetEntities();
|
||||
SceneObjectPart sop = null;
|
||||
|
||||
// FIXME: use a dictionary here
|
||||
foreach (EntityBase ent in EntityList)
|
||||
{
|
||||
if (ent is SceneObjectGroup)
|
||||
Entities.Find(
|
||||
delegate(EntityBase entity)
|
||||
{
|
||||
foreach (SceneObjectPart p in ((SceneObjectGroup) ent).GetParts())
|
||||
if (entity is SceneObjectGroup)
|
||||
{
|
||||
if (p.Name == name)
|
||||
foreach (SceneObjectPart p in ((SceneObjectGroup)entity).GetParts())
|
||||
{
|
||||
return p;
|
||||
if (p.Name == name)
|
||||
{
|
||||
sop = p;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
);
|
||||
|
||||
return sop;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1021,7 +1012,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// it
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected internal List<EntityBase> GetEntities()
|
||||
protected internal EntityBase[] GetEntities()
|
||||
{
|
||||
return Entities.GetEntities();
|
||||
}
|
||||
@@ -1030,7 +1021,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
|
||||
|
||||
List<EntityBase> EntityList = GetEntities();
|
||||
EntityBase[] EntityList = GetEntities();
|
||||
int limit = 0;
|
||||
foreach (EntityBase ent in EntityList)
|
||||
{
|
||||
@@ -1726,8 +1717,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
UUID objid = UUID.Zero;
|
||||
SceneObjectPart obj = null;
|
||||
|
||||
List<EntityBase> EntityList = GetEntities();
|
||||
foreach (EntityBase ent in EntityList)
|
||||
EntityBase[] entityList = GetEntities();
|
||||
foreach (EntityBase ent in entityList)
|
||||
{
|
||||
if (ent is SceneObjectGroup)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user