Improve consistency of locking for SOG.m_parts in order to avoid race conditions in linking and unlinking
parent
22fd00b002
commit
8031f8ec09
|
@ -232,7 +232,9 @@ namespace OpenSim.Data.MSSQL
|
|||
/// <param name="regionUUID"></param>
|
||||
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
||||
{
|
||||
_Log.InfoFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count);
|
||||
lock (obj.Children)
|
||||
{
|
||||
_Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count);
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
|
@ -291,7 +293,7 @@ namespace OpenSim.Data.MSSQL
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -135,6 +135,8 @@ namespace OpenSim.Data.MySQL
|
|||
dbcon.Open();
|
||||
MySqlCommand cmd = dbcon.CreateCommand();
|
||||
|
||||
lock (obj.Children)
|
||||
{
|
||||
foreach (SceneObjectPart prim in obj.Children.Values)
|
||||
{
|
||||
cmd.Parameters.Clear();
|
||||
|
@ -239,10 +241,12 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
|
||||
cmd.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveObject(UUID obj, UUID regionUUID)
|
||||
{
|
||||
|
|
|
@ -359,13 +359,16 @@ namespace OpenSim.Data.SQLite
|
|||
return;
|
||||
|
||||
lock (ds)
|
||||
{
|
||||
lock (obj.Children)
|
||||
{
|
||||
foreach (SceneObjectPart prim in obj.Children.Values)
|
||||
{
|
||||
// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
|
||||
// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
|
||||
addPrim(prim, obj.UUID, regionUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Commit();
|
||||
// m_log.Info("[Dump of prims]: " + ds.GetXml());
|
||||
|
|
|
@ -326,13 +326,16 @@ namespace OpenSim.Data.SQLiteLegacy
|
|||
return;
|
||||
|
||||
lock (ds)
|
||||
{
|
||||
lock (obj.Children)
|
||||
{
|
||||
foreach (SceneObjectPart prim in obj.Children.Values)
|
||||
{
|
||||
// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
|
||||
// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
|
||||
addPrim(prim, obj.UUID, regionUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Commit();
|
||||
// m_log.Info("[Dump of prims]: " + ds.GetXml());
|
||||
|
|
|
@ -406,7 +406,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
||||
{
|
||||
if (!m_scene.Permissions.CanRezObject(
|
||||
part.ParentGroup.Children.Count, remoteClient.AgentId, presence.AbsolutePosition))
|
||||
part.ParentGroup.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
|
||||
return;
|
||||
|
||||
presence.Appearance.DetachAttachment(itemID);
|
||||
|
|
|
@ -526,7 +526,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
group.RootPart.CreateSelected = true;
|
||||
|
||||
if (!m_Scene.Permissions.CanRezObject(
|
||||
group.Children.Count, remoteClient.AgentId, pos)
|
||||
group.PrimCount, remoteClient.AgentId, pos)
|
||||
&& !attachment)
|
||||
{
|
||||
// The client operates in no fail mode. It will
|
||||
|
@ -594,7 +594,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
rootPart.Name = item.Name;
|
||||
rootPart.Description = item.Description;
|
||||
|
||||
List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);
|
||||
List<SceneObjectPart> partList = null;
|
||||
lock (group.Children)
|
||||
partList = new List<SceneObjectPart>(group.Children.Values);
|
||||
|
||||
group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
|
||||
if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0)
|
||||
|
|
|
@ -243,6 +243,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
// to the same scene (when this is possible).
|
||||
sceneObject.ResetIDs();
|
||||
|
||||
lock (sceneObject.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
{
|
||||
if (!ResolveUserUuid(part.CreatorID))
|
||||
|
@ -277,6 +279,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_scene.AddRestoredSceneObject(sceneObject, true, false))
|
||||
{
|
||||
|
|
|
@ -128,7 +128,10 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
|
|||
group.SetOwnerId(remoteClient.AgentId);
|
||||
group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId);
|
||||
|
||||
List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);
|
||||
List<SceneObjectPart> partList = null;
|
||||
|
||||
lock (group.Children)
|
||||
partList = new List<SceneObjectPart>(group.Children.Values);
|
||||
|
||||
if (m_scene.Permissions.PropagatePermissions())
|
||||
{
|
||||
|
|
|
@ -227,7 +227,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
|||
{
|
||||
SceneObjectGroup mapdot = (SceneObjectGroup)obj;
|
||||
Color mapdotspot = Color.Gray; // Default color when prim color is white
|
||||
|
||||
// Loop over prim in group
|
||||
lock (mapdot.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in mapdot.Children.Values)
|
||||
{
|
||||
if (part == null)
|
||||
|
@ -339,7 +342,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
|||
|| mapdrawendY > ((int)Constants.RegionSize - 1))
|
||||
continue;
|
||||
|
||||
#region obb face reconstruction part duex
|
||||
#region obb face reconstruction part duex
|
||||
Vector3[] vertexes = new Vector3[8];
|
||||
|
||||
// float[] distance = new float[6];
|
||||
|
@ -443,7 +446,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
|||
FaceD[2] = vertexes[7];
|
||||
FaceC[3] = vertexes[7];
|
||||
FaceD[5] = vertexes[7];
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
//int wy = 0;
|
||||
|
||||
|
@ -498,6 +501,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
|||
//}
|
||||
} // Object is within 256m Z of terrain
|
||||
} // object is at least a meter wide
|
||||
} // mapdot.Children lock
|
||||
} // loop over group children
|
||||
} // entitybase is sceneobject group
|
||||
} // foreach loop over entities
|
||||
|
|
|
@ -1974,7 +1974,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (null == group)
|
||||
return null;
|
||||
|
||||
if (!Permissions.CanRezObject(group.Children.Count, item.OwnerID, pos))
|
||||
if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos))
|
||||
return null;
|
||||
|
||||
if (!Permissions.BypassPermissions())
|
||||
|
@ -2051,9 +2051,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
sog.SetGroup(groupID, remoteClient);
|
||||
sog.ScheduleGroupForFullUpdate();
|
||||
|
||||
lock (sog.Children)
|
||||
{
|
||||
foreach (SceneObjectPart child in sog.Children.Values)
|
||||
child.Inventory.ChangeInventoryOwner(ownerID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Permissions.CanEditObject(sog.UUID, remoteClient.AgentId))
|
||||
|
@ -2062,16 +2065,18 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (sog.GroupID != groupID)
|
||||
continue;
|
||||
|
||||
lock (sog.Children)
|
||||
{
|
||||
foreach (SceneObjectPart child in sog.Children.Values)
|
||||
{
|
||||
child.LastOwnerID = child.OwnerID;
|
||||
child.Inventory.ChangeInventoryOwner(groupID);
|
||||
}
|
||||
}
|
||||
|
||||
sog.SetOwnerId(groupID);
|
||||
sog.ApplyNextOwnerPermissions();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (uint localID in localIDs)
|
||||
|
|
|
@ -161,7 +161,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// We also need to check the children of this prim as they
|
||||
// can be selected as well and send property information
|
||||
bool foundPrim = false;
|
||||
foreach (KeyValuePair<UUID, SceneObjectPart> child in ((SceneObjectGroup) ent).Children)
|
||||
|
||||
SceneObjectGroup sog = ent as SceneObjectGroup;
|
||||
|
||||
lock (sog.Children)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, SceneObjectPart> child in (sog.Children))
|
||||
{
|
||||
if (child.Value.LocalId == primLocalID)
|
||||
{
|
||||
|
@ -170,7 +175,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (foundPrim) break;
|
||||
}
|
||||
|
||||
if (foundPrim)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1756,8 +1756,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
if (group.RootPart == null)
|
||||
{
|
||||
m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
|
||||
group.Children == null ? 0 : group.Children.Count);
|
||||
m_log.ErrorFormat(
|
||||
"[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
|
||||
group.Children == null ? 0 : group.PrimCount);
|
||||
}
|
||||
|
||||
AddRestoredSceneObject(group, true, true);
|
||||
|
@ -2064,6 +2065,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
group.RemoveScriptInstances(true);
|
||||
}
|
||||
|
||||
lock (group.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in group.Children.Values)
|
||||
{
|
||||
if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
|
||||
|
@ -2076,6 +2079,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
part.PhysActor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (rootPart.PhysActor != null)
|
||||
// {
|
||||
// PhysicsScene.RemovePrim(rootPart.PhysActor);
|
||||
|
@ -2426,15 +2431,17 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
// Force allocation of new LocalId
|
||||
//
|
||||
lock (sceneObject.Children)
|
||||
{
|
||||
foreach (SceneObjectPart p in sceneObject.Children.Values)
|
||||
p.LocalId = 0;
|
||||
}
|
||||
|
||||
if (sceneObject.IsAttachmentCheckFull()) // Attachment
|
||||
{
|
||||
sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
|
||||
sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
|
||||
|
||||
|
||||
// Don't sent a full update here because this will cause full updates to be sent twice for
|
||||
// attachments on region crossings, resulting in viewer glitches.
|
||||
AddRestoredSceneObject(sceneObject, false, false, false);
|
||||
|
@ -2447,7 +2454,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
if (sp != null)
|
||||
{
|
||||
|
||||
SceneObjectGroup grp = sceneObject;
|
||||
|
||||
m_log.DebugFormat(
|
||||
|
@ -2459,7 +2465,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
if (AttachmentsModule != null)
|
||||
AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -364,6 +364,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// "[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)
|
||||
|
@ -406,6 +408,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -420,11 +423,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
if (!resultOfObjectLinked)
|
||||
{
|
||||
m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count;
|
||||
SceneObjectGroup sog = Entities[uuid] as SceneObjectGroup;
|
||||
|
||||
lock (sog.Children)
|
||||
{
|
||||
m_numPrim -= sog.PrimCount;
|
||||
|
||||
if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
|
||||
{
|
||||
RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count);
|
||||
RemovePhysicalPrim(sog.PrimCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1603,7 +1611,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
if (part != null)
|
||||
{
|
||||
if (part.ParentGroup.Children.Count != 1) // Skip single
|
||||
if (part.ParentGroup.PrimCount != 1) // Skip single
|
||||
{
|
||||
if (part.LinkNum < 2) // Root
|
||||
rootParts.Add(part);
|
||||
|
@ -1631,8 +1639,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// However, editing linked parts and unlinking may be different
|
||||
//
|
||||
SceneObjectGroup group = root.ParentGroup;
|
||||
List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values);
|
||||
int numChildren = group.Children.Count;
|
||||
|
||||
List<SceneObjectPart> newSet = null;
|
||||
int numChildren = -1;
|
||||
|
||||
lock (group.Children)
|
||||
{
|
||||
newSet = new List<SceneObjectPart>(group.Children.Values);
|
||||
numChildren = group.PrimCount;
|
||||
}
|
||||
|
||||
// If there are prims left in a link set, but the root is
|
||||
// slated for unlink, we need to do this
|
||||
|
@ -1711,7 +1726,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
if (ent is SceneObjectGroup)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, SceneObjectPart> subent in ((SceneObjectGroup)ent).Children)
|
||||
SceneObjectGroup sog = ent as SceneObjectGroup;
|
||||
|
||||
lock (sog.Children)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, SceneObjectPart> subent in sog.Children)
|
||||
{
|
||||
if (subent.Value.LocalId == localID)
|
||||
{
|
||||
|
@ -1721,6 +1740,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Protip: In my day, we didn't call them searchable objects, we called them limited point-to-point joints
|
||||
//aka ObjectFlags.JointWheel = IncludeInSearch
|
||||
|
@ -1781,7 +1801,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
SceneObjectGroup original = GetGroupByPrim(originalPrimID);
|
||||
if (original != null)
|
||||
{
|
||||
if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition))
|
||||
if (m_parentScene.Permissions.CanDuplicateObject(
|
||||
original.PrimCount, original.UUID, AgentID, original.AbsolutePosition))
|
||||
{
|
||||
SceneObjectGroup copy = original.Copy(true);
|
||||
copy.AbsolutePosition = copy.AbsolutePosition + offset;
|
||||
|
|
|
@ -213,7 +213,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </summary>
|
||||
public int PrimCount
|
||||
{
|
||||
get { return m_parts.Count; }
|
||||
get { lock (m_parts) { return m_parts.Count; } }
|
||||
}
|
||||
|
||||
protected Quaternion m_rotation = Quaternion.Identity;
|
||||
|
@ -237,6 +237,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
/// <value>
|
||||
/// The parts of this scene object group. You must lock this property before using it.
|
||||
/// If you want to know the number of children, consider using the PrimCount property instead
|
||||
/// </value>
|
||||
public Dictionary<UUID, SceneObjectPart> Children
|
||||
{
|
||||
|
@ -298,6 +299,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
|
||||
}
|
||||
|
||||
if (RootPart.GetStatusSandbox())
|
||||
{
|
||||
if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
|
||||
|
@ -308,6 +310,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
|
@ -558,7 +561,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (m_rootPart.LocalId == 0)
|
||||
m_rootPart.LocalId = m_scene.AllocateLocalId();
|
||||
|
||||
// No need to lock here since the object isn't yet in a scene
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
if (Object.ReferenceEquals(part, m_rootPart))
|
||||
|
@ -574,6 +578,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
part.ParentID = m_rootPart.LocalId;
|
||||
//m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
|
||||
}
|
||||
}
|
||||
|
||||
ApplyPhysics(m_scene.m_physicalPrim);
|
||||
|
||||
|
@ -670,7 +675,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
minY = 256f;
|
||||
minZ = 8192f;
|
||||
|
||||
lock(m_parts);
|
||||
lock(m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
|
@ -995,10 +1000,13 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_rootPart.AttachedAvatar = agentID;
|
||||
|
||||
//Anakin Lohner bug #3839
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart p in m_parts.Values)
|
||||
{
|
||||
p.AttachedAvatar = agentID;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_rootPart.PhysActor != null)
|
||||
{
|
||||
|
@ -1065,11 +1073,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
AbsolutePosition = detachedpos;
|
||||
m_rootPart.AttachedAvatar = UUID.Zero;
|
||||
|
||||
//Anakin Lohner bug #3839
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart p in m_parts.Values)
|
||||
{
|
||||
p.AttachedAvatar = UUID.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
m_rootPart.SetParentLocalId(0);
|
||||
SetAttachmentPoint((byte)0);
|
||||
|
@ -1094,11 +1106,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
|
||||
m_rootPart.AttachedAvatar = UUID.Zero;
|
||||
|
||||
//Anakin Lohner bug #3839
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart p in m_parts.Values)
|
||||
{
|
||||
p.AttachedAvatar = UUID.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
m_rootPart.SetParentLocalId(0);
|
||||
//m_rootPart.SetAttachmentPoint((byte)0);
|
||||
|
@ -1160,8 +1176,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
part.ParentID = 0;
|
||||
part.LinkNum = 0;
|
||||
|
||||
// No locking required since the SOG should not be in the scene yet - one can't change root parts after
|
||||
// the scene object has been attached to the scene
|
||||
lock (m_parts)
|
||||
m_parts.Add(m_rootPart.UUID, m_rootPart);
|
||||
}
|
||||
|
||||
|
@ -1625,7 +1640,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Copy the given part as the root part of this scene object.
|
||||
/// </summary>
|
||||
/// <param name="part"></param>
|
||||
/// <param name="cAgentID"></param>
|
||||
|
@ -1882,11 +1897,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <param name="cGroupID"></param>
|
||||
public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
|
||||
{
|
||||
SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
|
||||
newPart.SetParent(this);
|
||||
SceneObjectPart newPart = null;
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
|
||||
newPart.SetParent(this);
|
||||
m_parts.Add(newPart.UUID, newPart);
|
||||
}
|
||||
|
||||
|
@ -1903,8 +1919,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </summary>
|
||||
public void ResetIDs()
|
||||
{
|
||||
// As this is only ever called for prims which are not currently part of the scene (and hence
|
||||
// not accessible by clients), there should be no need to lock
|
||||
lock (m_parts)
|
||||
{
|
||||
List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
|
||||
m_parts.Clear();
|
||||
foreach (SceneObjectPart part in partsList)
|
||||
|
@ -1913,6 +1929,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_parts.Add(part.UUID, part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -2136,10 +2153,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public SceneObjectPart GetChildPart(UUID primID)
|
||||
{
|
||||
SceneObjectPart childPart = null;
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
if (m_parts.ContainsKey(primID))
|
||||
{
|
||||
childPart = m_parts[primID];
|
||||
}
|
||||
}
|
||||
|
||||
return childPart;
|
||||
}
|
||||
|
||||
|
@ -2174,8 +2196,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <returns></returns>
|
||||
public bool HasChildPrim(UUID primID)
|
||||
{
|
||||
if (m_parts.ContainsKey(primID))
|
||||
lock (m_parts)
|
||||
{
|
||||
if (m_parts.ContainsKey(primID))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2370,10 +2393,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
lock (m_parts)
|
||||
{
|
||||
m_parts.Remove(linkPart.UUID);
|
||||
}
|
||||
|
||||
if (m_parts.Count == 1 && RootPart != null) //Single prim is left
|
||||
{
|
||||
RootPart.LinkNum = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (SceneObjectPart p in m_parts.Values)
|
||||
|
@ -2382,6 +2406,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
p.LinkNum--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
linkPart.ParentID = 0;
|
||||
linkPart.LinkNum = 0;
|
||||
|
@ -2761,10 +2786,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public void UpdatePermissions(UUID AgentID, byte field, uint localID,
|
||||
uint mask, byte addRemTF)
|
||||
{
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
part.UpdatePermissions(AgentID, field, localID, mask,
|
||||
addRemTF);
|
||||
part.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
|
||||
}
|
||||
|
||||
HasGroupChanged = true;
|
||||
}
|
||||
|
|
|
@ -601,7 +601,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
rootPart.Name = item.Name;
|
||||
rootPart.Description = item.Description;
|
||||
|
||||
List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);
|
||||
List<SceneObjectPart> partList = null;
|
||||
|
||||
lock (group.Children)
|
||||
partList = new List<SceneObjectPart>(group.Children.Values);
|
||||
|
||||
group.SetGroup(m_part.GroupID, null);
|
||||
|
||||
|
|
|
@ -121,6 +121,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
continue;
|
||||
temp = (SceneObjectGroup) currObj;
|
||||
|
||||
lock (temp.Children)
|
||||
{
|
||||
if (m_CMEntityHash.ContainsKey(temp.UUID))
|
||||
{
|
||||
foreach (SceneObjectPart part in temp.Children.Values)
|
||||
|
@ -133,6 +135,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
missingList.Add(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
return missingList;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -167,10 +167,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
|
||||
{
|
||||
// Deal with new parts not revisioned that have been deleted.
|
||||
lock (group.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in group.Children.Values)
|
||||
if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
||||
m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the latest revision of a region in xml form,
|
||||
|
@ -207,8 +210,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
{
|
||||
temp = SceneObjectSerializer.FromXml2Format(xml);
|
||||
temp.SetScene(scene);
|
||||
|
||||
lock (temp.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in temp.Children.Values)
|
||||
part.RegionHandle = scene.RegionInfo.RegionHandle;
|
||||
}
|
||||
|
||||
ReplacementList.Add(temp.UUID, (EntityBase)temp);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -338,6 +346,9 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
System.Collections.ArrayList auraList = new System.Collections.ArrayList();
|
||||
if (group == null)
|
||||
return null;
|
||||
|
||||
lock (group.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in group.Children.Values)
|
||||
{
|
||||
if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
||||
|
@ -347,6 +358,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return auraList;
|
||||
}
|
||||
|
||||
|
|
|
@ -186,10 +186,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll();
|
||||
|
||||
// Deal with new parts not revisioned that have been deleted.
|
||||
lock (group.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in group.Children.Values)
|
||||
if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
||||
((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void SendMetaEntitiesToNewClient(IClientAPI client)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -131,6 +131,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
DiffersFromSceneGroup = false;
|
||||
// if group is not contained in scene's list
|
||||
if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
|
||||
{
|
||||
lock (m_UnchangedEntity.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
|
||||
{
|
||||
|
@ -157,6 +159,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
}
|
||||
// otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
|
||||
}
|
||||
}
|
||||
|
||||
// a deleted part has no where to point a beam particle system,
|
||||
// if a metapart had a particle system (maybe it represented a moved part) remove it
|
||||
|
@ -180,8 +183,10 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
/// </summary>
|
||||
public bool HasChildPrim(UUID uuid)
|
||||
{
|
||||
lock (m_UnchangedEntity.Children)
|
||||
if (m_UnchangedEntity.Children.ContainsKey(uuid))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -189,10 +194,14 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
/// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId.
|
||||
/// </summary>
|
||||
public bool HasChildPrim(uint localID)
|
||||
{
|
||||
lock (m_UnchangedEntity.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
|
||||
if (part.LocalId == localID)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -228,6 +237,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
// Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
|
||||
// had originally saved.
|
||||
// m_Entity will NOT necessarily be the same entity as the user had saved.
|
||||
lock (m_UnchangedEntity.Children)
|
||||
{
|
||||
foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values)
|
||||
{
|
||||
//This is the part that we use to show changes.
|
||||
|
@ -309,6 +320,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
DiffersFromSceneGroup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
|
|
@ -150,6 +150,9 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
{
|
||||
//make new uuids
|
||||
Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>();
|
||||
|
||||
lock (m_Entity.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_Entity.Children.Values)
|
||||
{
|
||||
part.ResetIDs(part.LinkNum);
|
||||
|
@ -160,6 +163,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
m_Entity.RootPart.PhysActor = null;
|
||||
m_Entity.Children = parts;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
|
@ -173,14 +177,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
//This deletes the group without removing from any databases.
|
||||
//This is important because we are not IN any database.
|
||||
//m_Entity.FakeDeleteGroup();
|
||||
lock (m_Entity.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_Entity.Children.Values)
|
||||
client.SendKillObject(m_Entity.RegionHandle, part.LocalId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a kill object message to all clients, effectively "hiding" the metaentity even though it's still on the server.
|
||||
/// </summary>
|
||||
public virtual void HideFromAll()
|
||||
{
|
||||
lock (m_Entity.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_Entity.Children.Values)
|
||||
{
|
||||
|
@ -190,6 +199,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SendFullUpdate(IClientAPI client)
|
||||
{
|
||||
|
|
|
@ -185,15 +185,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
|
|||
get
|
||||
{
|
||||
SceneObjectPart my = GetSOP();
|
||||
IObject[] rets = null;
|
||||
|
||||
lock (my.ParentGroup.Children)
|
||||
{
|
||||
int total = my.ParentGroup.Children.Count;
|
||||
|
||||
IObject[] rets = new IObject[total];
|
||||
rets = new IObject[total];
|
||||
|
||||
int i = 0;
|
||||
foreach (KeyValuePair<UUID, SceneObjectPart> pair in my.ParentGroup.Children)
|
||||
{
|
||||
rets[i++] = new SOPObject(m_rootScene, pair.Value.LocalId, m_security);
|
||||
}
|
||||
}
|
||||
|
||||
return rets;
|
||||
}
|
||||
|
|
|
@ -235,7 +235,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
{
|
||||
case ScriptBaseClass.LINK_SET:
|
||||
if (m_host.ParentGroup != null)
|
||||
{
|
||||
lock (m_host.ParentGroup.Children)
|
||||
return new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
|
||||
}
|
||||
return ret;
|
||||
|
||||
case ScriptBaseClass.LINK_ROOT:
|
||||
|
@ -250,7 +253,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
case ScriptBaseClass.LINK_ALL_OTHERS:
|
||||
if (m_host.ParentGroup == null)
|
||||
return new List<SceneObjectPart>();
|
||||
|
||||
lock (m_host.ParentGroup.Children)
|
||||
ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
|
||||
|
||||
if (ret.Contains(m_host))
|
||||
ret.Remove(m_host);
|
||||
return ret;
|
||||
|
@ -258,7 +264,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
case ScriptBaseClass.LINK_ALL_CHILDREN:
|
||||
if (m_host.ParentGroup == null)
|
||||
return new List<SceneObjectPart>();
|
||||
|
||||
lock (m_host.ParentGroup.Children)
|
||||
ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
|
||||
|
||||
if (ret.Contains(m_host.ParentGroup.RootPart))
|
||||
ret.Remove(m_host.ParentGroup.RootPart);
|
||||
return ret;
|
||||
|
@ -1178,6 +1187,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
if (group == null)
|
||||
return;
|
||||
bool allow = true;
|
||||
|
||||
lock (group.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in group.Children.Values)
|
||||
{
|
||||
if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys)
|
||||
|
@ -1186,6 +1198,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!allow)
|
||||
return;
|
||||
|
@ -3492,7 +3505,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
if (m_host.ParentGroup.Children.Count > 1)
|
||||
if (m_host.ParentGroup.PrimCount > 1)
|
||||
{
|
||||
return m_host.LinkNum;
|
||||
}
|
||||
|
@ -3604,6 +3617,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
case ScriptBaseClass.LINK_ALL_OTHERS:
|
||||
case ScriptBaseClass.LINK_ALL_CHILDREN:
|
||||
case ScriptBaseClass.LINK_THIS:
|
||||
lock (parentPrim.Children)
|
||||
{
|
||||
foreach (SceneObjectPart part in parentPrim.Children.Values)
|
||||
{
|
||||
if (part.UUID != m_host.UUID)
|
||||
|
@ -3613,6 +3628,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
childPrim = parentPrim.GetLinkNumPart(linknum);
|
||||
if (childPrim.UUID == m_host.UUID)
|
||||
|
@ -3623,6 +3639,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
if (linknum == ScriptBaseClass.LINK_ROOT)
|
||||
{
|
||||
// Restructuring Multiple Prims.
|
||||
lock (parentPrim.Children)
|
||||
{
|
||||
List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
|
||||
parts.Remove(parentPrim.RootPart);
|
||||
foreach (SceneObjectPart part in parts)
|
||||
|
@ -3646,6 +3664,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
newRoot.ParentGroup.ScheduleGroupForFullUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (childPrim == null)
|
||||
|
@ -3665,6 +3684,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
if (parentPrim.RootPart.AttachmentPoint != 0)
|
||||
return; // Fail silently if attached
|
||||
|
||||
lock (parentPrim.Children)
|
||||
{
|
||||
List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
|
||||
parts.Remove(parentPrim.RootPart);
|
||||
|
||||
|
@ -3676,6 +3697,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
parentPrim.HasGroupChanged = true;
|
||||
parentPrim.ScheduleGroupForFullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public LSL_String llGetLinkKey(int linknum)
|
||||
{
|
||||
|
@ -4200,7 +4222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
{
|
||||
partItemID = item.ItemID;
|
||||
int linkNumber = m_host.LinkNum;
|
||||
if (m_host.ParentGroup.Children.Count == 1)
|
||||
if (m_host.ParentGroup.PrimCount == 1)
|
||||
linkNumber = 0;
|
||||
|
||||
object[] resobj = new object[]
|
||||
|
|
|
@ -209,6 +209,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
|||
else
|
||||
Type = 0x02; // Passive
|
||||
|
||||
lock (part.ParentGroup.Children)
|
||||
{
|
||||
foreach (SceneObjectPart p in part.ParentGroup.Children.Values)
|
||||
{
|
||||
if (p.Inventory.ContainsScripts())
|
||||
|
@ -217,6 +219,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Position = new LSL_Types.Vector3(part.AbsolutePosition.X,
|
||||
part.AbsolutePosition.Y,
|
||||
|
|
Loading…
Reference in New Issue