From 46c6c35d4868e4ff538bdc2c65a7fade936c0ce1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 25 Aug 2010 22:46:49 +0100 Subject: refactor: Push item retrieval and fixing part of Scene.RezObject() down into SceneObjectPartInventory --- .../Framework/Interfaces/IEntityInventory.cs | 12 ++++ OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 59 ++----------------- .../Framework/Scenes/SceneObjectPartInventory.cs | 66 +++++++++++++++++++++- 3 files changed, 82 insertions(+), 55 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index fd43923..ae2e844 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -29,6 +29,7 @@ using System.Collections.Generic; using System.Collections; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.Framework.Interfaces { @@ -153,6 +154,17 @@ namespace OpenSim.Region.Framework.Interfaces /// If no inventory item has that name then an empty list is returned. /// IList GetInventoryItems(string name); + + /// + /// Get the scene object referenced by an inventory item. + /// + /// + /// This is returned in a 'rez ready' state. That is, name, description, permissions and other details have + /// been adjusted to reflect the part and item from which it originates. + /// + /// + /// The scene object. Null if the scene object asset couldn't be found + SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item); /// /// Update an existing inventory item. diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 01be491..9fef8f4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1969,60 +1969,13 @@ namespace OpenSim.Region.Framework.Scenes if (null == item) return null; - UUID ownerID = item.OwnerID; - AssetBase rezAsset = AssetService.Get(item.AssetID.ToString()); - - if (null == rezAsset) - return null; - - string xmlData = Utils.BytesToString(rezAsset.Data); - SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); - - if (!Permissions.CanRezObject(group.Children.Count, ownerID, pos)) + SceneObjectGroup group = sourcePart.Inventory.GetRezReadySceneObject(item); + + if (null == group) return null; - - group.ResetIDs(); - - SceneObjectPart rootPart = group.GetChildPart(group.UUID); - - // Since renaming the item in the inventory does not affect the name stored - // in the serialization, transfer the correct name from the inventory to the - // object itself before we rez. - rootPart.Name = item.Name; - rootPart.Description = item.Description; - - List partList = new List(group.Children.Values); - - group.SetGroup(sourcePart.GroupID, null); - - if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) - { - if (Permissions.PropagatePermissions()) - { - foreach (SceneObjectPart part in partList) - { - part.EveryoneMask = item.EveryonePermissions; - part.NextOwnerMask = item.NextPermissions; - } - - group.ApplyNextOwnerPermissions(); - } - } - - foreach (SceneObjectPart part in partList) - { - if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) - { - part.LastOwnerID = part.OwnerID; - part.OwnerID = item.OwnerID; - part.Inventory.ChangeInventoryOwner(item.OwnerID); - } - - part.EveryoneMask = item.EveryonePermissions; - part.NextOwnerMask = item.NextPermissions; - } - rootPart.TrimPermissions(); + if (!Permissions.CanRezObject(group.Children.Count, item.OwnerID, pos)) + return null; if (!Permissions.BypassPermissions()) { @@ -2038,7 +1991,7 @@ namespace OpenSim.Region.Framework.Scenes group.ScheduleGroupForFullUpdate(); - return rootPart.ParentGroup; + return group; } public virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 4ae53a2..84b7365 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -37,6 +37,7 @@ using log4net; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes.Scripting; +using OpenSim.Region.Framework.Scenes.Serialization; namespace OpenSim.Region.Framework.Scenes { @@ -574,6 +575,68 @@ namespace OpenSim.Region.Framework.Scenes return items; } + public SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item) + { + UUID ownerID = item.OwnerID; + AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); + + if (null == rezAsset) + { + m_log.WarnFormat( + "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", + item.AssetID, item.Name, m_part.Name); + return null; + } + + string xmlData = Utils.BytesToString(rezAsset.Data); + SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); + + group.ResetIDs(); + + SceneObjectPart rootPart = group.GetChildPart(group.UUID); + + // Since renaming the item in the inventory does not affect the name stored + // in the serialization, transfer the correct name from the inventory to the + // object itself before we rez. + rootPart.Name = item.Name; + rootPart.Description = item.Description; + + List partList = new List(group.Children.Values); + + group.SetGroup(m_part.GroupID, null); + + if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) + { + if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) + { + foreach (SceneObjectPart part in partList) + { + part.EveryoneMask = item.EveryonePermissions; + part.NextOwnerMask = item.NextPermissions; + } + + group.ApplyNextOwnerPermissions(); + } + } + + foreach (SceneObjectPart part in partList) + { + if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) + { + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.OwnerID; + part.Inventory.ChangeInventoryOwner(item.OwnerID); + } + + part.EveryoneMask = item.EveryonePermissions; + part.NextOwnerMask = item.NextPermissions; + } + + rootPart.TrimPermissions(); + + return group; + } + /// /// Update an existing inventory item. /// @@ -1029,6 +1092,5 @@ namespace OpenSim.Region.Framework.Scenes } } } - } -} +} \ No newline at end of file -- cgit v1.1 From 24d06b12c2c361305dfcfd78497abb4bec3e3a38 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 25 Aug 2010 23:05:54 +0100 Subject: If setting SOG.UUID, update the SOG.m_parts index as well as the root part UUID Being able to change a SOG.UUID is useful for region modules that want to supply their own UUID, before the object is rezzed --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 117f869..952d280 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -335,7 +335,16 @@ namespace OpenSim.Region.Framework.Scenes public override UUID UUID { get { return m_rootPart.UUID; } - set { m_rootPart.UUID = value; } + set + { + m_rootPart.UUID = value; + + lock (m_parts) + { + m_parts.Remove(m_rootPart.UUID); + m_parts.Add(m_rootPart.UUID, m_rootPart); + } + } } public UUID OwnerID -- cgit v1.1 From 8031f8ec09df4f654c86a9c7bc498664f7b9d9dc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 26 Aug 2010 00:08:53 +0100 Subject: Improve consistency of locking for SOG.m_parts in order to avoid race conditions in linking and unlinking --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 21 ++-- .../Framework/Scenes/Scene.PacketHandlers.cs | 38 +++--- OpenSim/Region/Framework/Scenes/Scene.cs | 35 +++--- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 111 ++++++++++------- .../Region/Framework/Scenes/SceneObjectGroup.cs | 131 +++++++++++++-------- .../Framework/Scenes/SceneObjectPartInventory.cs | 5 +- 6 files changed, 205 insertions(+), 136 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 9fef8f4..379128a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -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,8 +2051,11 @@ namespace OpenSim.Region.Framework.Scenes sog.SetGroup(groupID, remoteClient); sog.ScheduleGroupForFullUpdate(); - foreach (SceneObjectPart child in sog.Children.Values) - child.Inventory.ChangeInventoryOwner(ownerID); + lock (sog.Children) + { + foreach (SceneObjectPart child in sog.Children.Values) + child.Inventory.ChangeInventoryOwner(ownerID); + } } else { @@ -2062,16 +2065,18 @@ namespace OpenSim.Region.Framework.Scenes if (sog.GroupID != groupID) continue; - foreach (SceneObjectPart child in sog.Children.Values) + lock (sog.Children) { - child.LastOwnerID = child.OwnerID; - child.Inventory.ChangeInventoryOwner(groupID); + 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) diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index e25b1f1..9f1575d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -156,21 +156,29 @@ namespace OpenSim.Region.Framework.Scenes } break; } - else - { - // 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 child in ((SceneObjectGroup) ent).Children) - { - if (child.Value.LocalId == primLocalID) - { - child.Value.GetProperties(remoteClient); - foundPrim = true; - break; - } - } - if (foundPrim) break; + else + { + // We also need to check the children of this prim as they + // can be selected as well and send property information + bool foundPrim = false; + + SceneObjectGroup sog = ent as SceneObjectGroup; + + lock (sog.Children) + { + foreach (KeyValuePair child in (sog.Children)) + { + if (child.Value.LocalId == primLocalID) + { + child.Value.GetProperties(remoteClient); + foundPrim = true; + break; + } + } + } + + if (foundPrim) + break; } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b808c6d..8556105 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -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,18 +2065,22 @@ namespace OpenSim.Region.Framework.Scenes group.RemoveScriptInstances(true); } - foreach (SceneObjectPart part in group.Children.Values) + lock (group.Children) { - if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) + foreach (SceneObjectPart part in group.Children.Values) { - PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? - } - else if (part.PhysActor != null) - { - PhysicsScene.RemovePrim(part.PhysActor); - part.PhysActor = null; + if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) + { + PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? + } + else if (part.PhysActor != null) + { + PhysicsScene.RemovePrim(part.PhysActor); + part.PhysActor = null; + } } } + // if (rootPart.PhysActor != null) // { // PhysicsScene.RemovePrim(rootPart.PhysActor); @@ -2426,14 +2431,16 @@ namespace OpenSim.Region.Framework.Scenes // Force allocation of new LocalId // - foreach (SceneObjectPart p in sceneObject.Children.Values) - p.LocalId = 0; + 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. @@ -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 { diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 31faeec..2b24706 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -364,45 +364,48 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE GRAPH]: Adding object {0} {1} to region {2}", // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); - if (m_parentScene.m_clampPrimSize) + lock (sceneObject.Children) { - foreach (SceneObjectPart part in sceneObject.Children.Values) + if (m_parentScene.m_clampPrimSize) { - 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; + 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; + } } - } + + sceneObject.AttachToScene(m_parentScene); + + if (sendClientUpdates) + sceneObject.ScheduleGroupForFullUpdate(); + + Entities.Add(sceneObject); + m_numPrim += sceneObject.Children.Count; - sceneObject.AttachToScene(m_parentScene); + if (attachToBackup) + sceneObject.AttachToBackup(); - if (sendClientUpdates) - sceneObject.ScheduleGroupForFullUpdate(); - - Entities.Add(sceneObject); - m_numPrim += sceneObject.Children.Count; - - if (attachToBackup) - sceneObject.AttachToBackup(); - - if (OnObjectCreate != null) - OnObjectCreate(sceneObject); - - lock (m_dictionary_lock) - { - SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; - SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; - foreach (SceneObjectPart part in sceneObject.Children.Values) + if (OnObjectCreate != null) + OnObjectCreate(sceneObject); + + lock (m_dictionary_lock) { - SceneObjectGroupsByFullID[part.UUID] = sceneObject; - SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; + SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; + SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; + foreach (SceneObjectPart part in sceneObject.Children.Values) + { + SceneObjectGroupsByFullID[part.UUID] = sceneObject; + SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; + } } } } @@ -420,11 +423,16 @@ namespace OpenSim.Region.Framework.Scenes { if (!resultOfObjectLinked) { - m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count; - - if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) + SceneObjectGroup sog = Entities[uuid] as SceneObjectGroup; + + lock (sog.Children) { - RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count); + m_numPrim -= sog.PrimCount; + + if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) + { + 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 newSet = new List(group.Children.Values); - int numChildren = group.Children.Count; + + List newSet = null; + int numChildren = -1; + + lock (group.Children) + { + newSet = new List(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,12 +1726,17 @@ namespace OpenSim.Region.Framework.Scenes { if (ent is SceneObjectGroup) { - foreach (KeyValuePair subent in ((SceneObjectGroup)ent).Children) + SceneObjectGroup sog = ent as SceneObjectGroup; + + lock (sog.Children) { - if (subent.Value.LocalId == localID) + foreach (KeyValuePair subent in sog.Children) { - objid = subent.Key; - obj = subent.Value; + if (subent.Value.LocalId == localID) + { + objid = subent.Key; + obj = subent.Value; + } } } } @@ -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; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 952d280..5ee8d73 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -213,7 +213,7 @@ namespace OpenSim.Region.Framework.Scenes /// 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 /// /// 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 /// public Dictionary 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,21 +561,23 @@ 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 - foreach (SceneObjectPart part in m_parts.Values) + lock (m_parts) { - if (Object.ReferenceEquals(part, m_rootPart)) - { - continue; - } - - if (part.LocalId == 0) + foreach (SceneObjectPart part in m_parts.Values) { - part.LocalId = m_scene.AllocateLocalId(); + if (Object.ReferenceEquals(part, m_rootPart)) + { + continue; + } + + if (part.LocalId == 0) + { + part.LocalId = m_scene.AllocateLocalId(); + } + + 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); } - - 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,9 +1000,12 @@ namespace OpenSim.Region.Framework.Scenes m_rootPart.AttachedAvatar = agentID; //Anakin Lohner bug #3839 - foreach (SceneObjectPart p in m_parts.Values) + lock (m_parts) { - p.AttachedAvatar = agentID; + foreach (SceneObjectPart p in m_parts.Values) + { + p.AttachedAvatar = agentID; + } } if (m_rootPart.PhysActor != null) @@ -1065,10 +1073,14 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = detachedpos; m_rootPart.AttachedAvatar = UUID.Zero; - //Anakin Lohner bug #3839 - foreach (SceneObjectPart p in m_parts.Values) + + //Anakin Lohner bug #3839 + lock (m_parts) { - p.AttachedAvatar = UUID.Zero; + foreach (SceneObjectPart p in m_parts.Values) + { + p.AttachedAvatar = UUID.Zero; + } } m_rootPart.SetParentLocalId(0); @@ -1094,10 +1106,14 @@ namespace OpenSim.Region.Framework.Scenes } m_rootPart.AttachedAvatar = UUID.Zero; + //Anakin Lohner bug #3839 - foreach (SceneObjectPart p in m_parts.Values) + lock (m_parts) { - p.AttachedAvatar = UUID.Zero; + foreach (SceneObjectPart p in m_parts.Values) + { + p.AttachedAvatar = UUID.Zero; + } } m_rootPart.SetParentLocalId(0); @@ -1160,9 +1176,8 @@ 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 - m_parts.Add(m_rootPart.UUID, m_rootPart); + lock (m_parts) + m_parts.Add(m_rootPart.UUID, m_rootPart); } /// @@ -1625,7 +1640,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// + /// Copy the given part as the root part of this scene object. /// /// /// @@ -1882,11 +1897,12 @@ namespace OpenSim.Region.Framework.Scenes /// 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,14 +1919,15 @@ namespace OpenSim.Region.Framework.Scenes /// 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 - List partsList = new List(m_parts.Values); - m_parts.Clear(); - foreach (SceneObjectPart part in partsList) + lock (m_parts) { - part.ResetIDs(part.LinkNum); // Don't change link nums - m_parts.Add(part.UUID, part); + List partsList = new List(m_parts.Values); + m_parts.Clear(); + foreach (SceneObjectPart part in partsList) + { + part.ResetIDs(part.LinkNum); // Don't change link nums + m_parts.Add(part.UUID, part); + } } } @@ -2136,10 +2153,15 @@ namespace OpenSim.Region.Framework.Scenes public SceneObjectPart GetChildPart(UUID primID) { SceneObjectPart childPart = null; - if (m_parts.ContainsKey(primID)) + + lock (m_parts) { - childPart = m_parts[primID]; + if (m_parts.ContainsKey(primID)) + { + childPart = m_parts[primID]; + } } + return childPart; } @@ -2174,9 +2196,10 @@ namespace OpenSim.Region.Framework.Scenes /// public bool HasChildPrim(UUID primID) { - if (m_parts.ContainsKey(primID)) + lock (m_parts) { - return true; + if (m_parts.ContainsKey(primID)) + return true; } return false; @@ -2370,17 +2393,19 @@ 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) + + if (m_parts.Count == 1 && RootPart != null) //Single prim is left { - if (p.LinkNum > linkPart.LinkNum) - p.LinkNum--; + RootPart.LinkNum = 0; } + else + { + foreach (SceneObjectPart p in m_parts.Values) + { + if (p.LinkNum > linkPart.LinkNum) + p.LinkNum--; + } + } } linkPart.ParentID = 0; @@ -2762,9 +2787,11 @@ namespace OpenSim.Region.Framework.Scenes public void UpdatePermissions(UUID AgentID, byte field, uint localID, uint mask, byte addRemTF) { - foreach (SceneObjectPart part in m_parts.Values) - part.UpdatePermissions(AgentID, field, localID, mask, - addRemTF); + lock (m_parts) + { + foreach (SceneObjectPart part in m_parts.Values) + part.UpdatePermissions(AgentID, field, localID, mask, addRemTF); + } HasGroupChanged = true; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 84b7365..e08fa77 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -601,7 +601,10 @@ namespace OpenSim.Region.Framework.Scenes rootPart.Name = item.Name; rootPart.Description = item.Description; - List partList = new List(group.Children.Values); + List partList = null; + + lock (group.Children) + partList = new List(group.Children.Values); group.SetGroup(m_part.GroupID, null); -- cgit v1.1 From 166ab59420f34e21fcd9493c1941d7cf43729ca6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 26 Aug 2010 00:15:26 +0100 Subject: replace m_parts.Count linknum with 0 in CopyRootPart since m_parts.Count is always 0 (and any other number would cause an error anyway) --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 5ee8d73..fc5eeed 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1647,7 +1647,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) { - SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed)); + SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); } public void ScriptSetPhysicsStatus(bool UsePhysics) -- cgit v1.1