Improve liveness by operating on list copies of SOG.Children where appropriate

prebuild-update
Justin Clark-Casey (justincc) 2010-08-28 00:40:33 +01:00
parent 4f9931ec10
commit 1c0b4457cd
9 changed files with 386 additions and 373 deletions

View File

@ -349,7 +349,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
public void TestLoadIarPathStartsWithSlash() public void TestLoadIarPathStartsWithSlash()
{ {
TestHelper.InMethod(); TestHelper.InMethod();
log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
SerialiserModule serialiserModule = new SerialiserModule(); SerialiserModule serialiserModule = new SerialiserModule();
InventoryArchiverModule archiverModule = new InventoryArchiverModule(true); InventoryArchiverModule archiverModule = new InventoryArchiverModule(true);

View File

@ -243,9 +243,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// to the same scene (when this is possible). // to the same scene (when this is possible).
sceneObject.ResetIDs(); sceneObject.ResetIDs();
List<SceneObjectPart> partList = null;
lock (sceneObject.Children) lock (sceneObject.Children)
{ partList = new List<SceneObjectPart>(sceneObject.Children.Values);
foreach (SceneObjectPart part in sceneObject.Children.Values)
foreach (SceneObjectPart part in partList)
{ {
if (!ResolveUserUuid(part.CreatorID)) if (!ResolveUserUuid(part.CreatorID))
part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
@ -279,7 +281,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
} }
} }
} }
}
if (m_scene.AddRestoredSceneObject(sceneObject, true, false)) if (m_scene.AddRestoredSceneObject(sceneObject, true, false))
{ {

View File

@ -229,9 +229,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
Color mapdotspot = Color.Gray; // Default color when prim color is white Color mapdotspot = Color.Gray; // Default color when prim color is white
// Loop over prim in group // Loop over prim in group
List<SceneObjectPart> partList = null;
lock (mapdot.Children) lock (mapdot.Children)
{ partList = new List<SceneObjectPart>(mapdot.Children.Values);
foreach (SceneObjectPart part in mapdot.Children.Values)
foreach (SceneObjectPart part in partList)
{ {
if (part == null) if (part == null)
continue; continue;
@ -501,7 +503,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
//} //}
} // Object is within 256m Z of terrain } // Object is within 256m Z of terrain
} // object is at least a meter wide } // object is at least a meter wide
} // mapdot.Children lock
} // loop over group children } // loop over group children
} // entitybase is sceneobject group } // entitybase is sceneobject group
} // foreach loop over entities } // foreach loop over entities

View File

@ -2004,12 +2004,13 @@ namespace OpenSim.Region.Framework.Scenes
sog.SetGroup(groupID, remoteClient); sog.SetGroup(groupID, remoteClient);
sog.ScheduleGroupForFullUpdate(); sog.ScheduleGroupForFullUpdate();
List<SceneObjectPart> partList = null;
lock (sog.Children) lock (sog.Children)
{ partList = new List<SceneObjectPart>(sog.Children.Values);
foreach (SceneObjectPart child in sog.Children.Values)
foreach (SceneObjectPart child in partList)
child.Inventory.ChangeInventoryOwner(ownerID); child.Inventory.ChangeInventoryOwner(ownerID);
} }
}
else else
{ {
if (!Permissions.CanEditObject(sog.UUID, remoteClient.AgentId)) if (!Permissions.CanEditObject(sog.UUID, remoteClient.AgentId))
@ -2018,14 +2019,15 @@ namespace OpenSim.Region.Framework.Scenes
if (sog.GroupID != groupID) if (sog.GroupID != groupID)
continue; continue;
List<SceneObjectPart> partList = null;
lock (sog.Children) lock (sog.Children)
{ partList = new List<SceneObjectPart>(sog.Children.Values);
foreach (SceneObjectPart child in sog.Children.Values)
foreach (SceneObjectPart child in partList)
{ {
child.LastOwnerID = child.OwnerID; child.LastOwnerID = child.OwnerID;
child.Inventory.ChangeInventoryOwner(groupID); child.Inventory.ChangeInventoryOwner(groupID);
} }
}
sog.SetOwnerId(groupID); sog.SetOwnerId(groupID);
sog.ApplyNextOwnerPermissions(); sog.ApplyNextOwnerPermissions();

View File

@ -164,18 +164,19 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectGroup sog = ent as SceneObjectGroup; SceneObjectGroup sog = ent as SceneObjectGroup;
List<SceneObjectPart> partList = null;
lock (sog.Children) lock (sog.Children)
partList = new List<SceneObjectPart>(sog.Children.Values);
foreach (SceneObjectPart part in partList)
{ {
foreach (KeyValuePair<UUID, SceneObjectPart> child in (sog.Children)) if (part.LocalId == primLocalID)
{ {
if (child.Value.LocalId == primLocalID) part.GetProperties(remoteClient);
{
child.Value.GetProperties(remoteClient);
foundPrim = true; foundPrim = true;
break; break;
} }
} }
}
if (foundPrim) if (foundPrim)
break; break;

View File

@ -2065,9 +2065,11 @@ namespace OpenSim.Region.Framework.Scenes
group.RemoveScriptInstances(true); group.RemoveScriptInstances(true);
} }
List<SceneObjectPart> partList = null;
lock (group.Children) lock (group.Children)
{ partList = new List<SceneObjectPart>(group.Children.Values);
foreach (SceneObjectPart part in group.Children.Values)
foreach (SceneObjectPart part in partList)
{ {
if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
{ {
@ -2079,7 +2081,6 @@ namespace OpenSim.Region.Framework.Scenes
part.PhysActor = null; part.PhysActor = null;
} }
} }
}
// if (rootPart.PhysActor != null) // if (rootPart.PhysActor != null)
// { // {

View File

@ -381,13 +381,15 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
m_numPrim += sceneObject.Children.Count;
}
sceneObject.AttachToScene(m_parentScene); sceneObject.AttachToScene(m_parentScene);
if (sendClientUpdates) if (sendClientUpdates)
sceneObject.ScheduleGroupForFullUpdate(); sceneObject.ScheduleGroupForFullUpdate();
Entities.Add(sceneObject); Entities.Add(sceneObject);
m_numPrim += sceneObject.Children.Count;
if (attachToBackup) if (attachToBackup)
sceneObject.AttachToBackup(); sceneObject.AttachToBackup();
@ -409,7 +411,6 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
} }
} }
}
return true; return true;
} }

View File

@ -237,6 +237,8 @@ namespace OpenSim.Region.Framework.Scenes
/// <value> /// <value>
/// The parts of this scene object group. You must lock this property before using it. /// The parts of this scene object group. You must lock this property before using it.
/// If you're doing anything other than reading values, please take a copy of the values rather than locking
/// the dictionary for the entirety of the operation. This increases liveness and reduces the danger of deadlock
/// If you want to know the number of children, consider using the PrimCount property instead /// If you want to know the number of children, consider using the PrimCount property instead
/// </value> /// </value>
public Dictionary<UUID, SceneObjectPart> Children public Dictionary<UUID, SceneObjectPart> Children
@ -1968,8 +1970,6 @@ namespace OpenSim.Region.Framework.Scenes
//if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
// return; // return;
lock (m_parts)
{
bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f))
@ -1984,14 +1984,17 @@ namespace OpenSim.Region.Framework.Scenes
lastPhysGroupRot = GroupRotation; lastPhysGroupRot = GroupRotation;
} }
foreach (SceneObjectPart part in m_parts.Values) List<SceneObjectPart> partList = null;
lock (m_parts)
partList = new List<SceneObjectPart>(m_parts.Values);
foreach (SceneObjectPart part in partList)
{ {
if (!IsSelected) if (!IsSelected)
part.UpdateLookAt(); part.UpdateLookAt();
part.SendScheduledUpdates(); part.SendScheduledUpdates();
} }
} }
}
public void ScheduleFullUpdateToAvatar(ScenePresence presence) public void ScheduleFullUpdateToAvatar(ScenePresence presence)
{ {
@ -2787,11 +2790,12 @@ namespace OpenSim.Region.Framework.Scenes
public void UpdatePermissions(UUID AgentID, byte field, uint localID, public void UpdatePermissions(UUID AgentID, byte field, uint localID,
uint mask, byte addRemTF) uint mask, byte addRemTF)
{ {
List<SceneObjectPart> partList = null;
lock (m_parts) lock (m_parts)
{ partList = new List<SceneObjectPart>(m_parts.Values);
foreach (SceneObjectPart part in m_parts.Values)
foreach (SceneObjectPart part in partList)
part.UpdatePermissions(AgentID, field, localID, mask, addRemTF); part.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
}
HasGroupChanged = true; HasGroupChanged = true;
} }

View File

@ -187,17 +187,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
SceneObjectPart my = GetSOP(); SceneObjectPart my = GetSOP();
IObject[] rets = null; IObject[] rets = null;
lock (my.ParentGroup.Children) int total = my.ParentGroup.PrimCount;
{
int total = my.ParentGroup.Children.Count;
rets = new IObject[total]; rets = new IObject[total];
int i = 0; int i = 0;
foreach (KeyValuePair<UUID, SceneObjectPart> pair in my.ParentGroup.Children)
List<SceneObjectPart> partList = null;
lock (my.ParentGroup.Children)
partList = new List<SceneObjectPart>(my.ParentGroup.Children.Values);
foreach (SceneObjectPart part in partList)
{ {
rets[i++] = new SOPObject(m_rootScene, pair.Value.LocalId, m_security); rets[i++] = new SOPObject(m_rootScene, part.LocalId, m_security);
}
} }
return rets; return rets;