From d54b6608a7acfa7fc9fd074f2fbd241519067fcb Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Mon, 17 Nov 2008 15:40:27 +0000 Subject: [PATCH] * Stop nulling SOG.m_rootPart and parts on object deletion * This renders RootPart == null checks useless - the replacement is to check SOG.IsDeleted. However, in many cases this will not be necessary since updates to deleted parts will not be sent to the client * This should remove any remaining race conditions where an object is deleted while another thread is yet to obtain the root part to perform some operation * Doing this is probably a necessary prerequisite to moving to a model without a separate SOG and SOP * Unfortunately it's not possible to eliminate all RootPart == null checks since in some contexts it is currently used to check whether an object was created successfully --- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 2 +- .../Region/Environment/Scenes/Scene.Inventory.cs | 4 ++-- OpenSim/Region/Environment/Scenes/Scene.cs | 10 +++++----- .../Environment/Scenes/SceneObjectGroup.cs | 16 ++++++---------- .../Region/Environment/Scenes/SceneObjectPart.cs | 16 ++++++++-------- .../Region/Environment/Scenes/ScenePresence.cs | 10 +++++----- .../Shared/Api/Implementation/LSL_Api.cs | 16 ++++++++-------- 7 files changed, 35 insertions(+), 39 deletions(-) diff --git a/OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs index 706ba6a9de..442b40de96 100644 --- a/OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -126,7 +126,7 @@ namespace OpenSim.Region.Environment.Scenes "[SCENE]: Sending deleted object to user's inventory, {0} item(s) remaining.", left); x = m_inventoryDeletes.Dequeue(); - if (x.objectGroup.RootPart != null) + if (!x.objectGroup.IsDeleted) { try { diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index 9ad8382a4d..cc8501d808 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs @@ -1552,7 +1552,7 @@ namespace OpenSim.Region.Environment.Scenes if (part == null) return; - if (part.ParentGroup == null || part.ParentGroup.RootPart == null) + if (part.ParentGroup == null || part.ParentGroup.IsDeleted) return; // Can't delete child prims @@ -2379,7 +2379,7 @@ namespace OpenSim.Region.Environment.Scenes public UUID RezSingleAttachment(SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { - if (att.RootPart != null) + if (!att.IsDeleted) AttachmentPt = att.RootPart.AttachmentPoint; ScenePresence presence; diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index c0551607bf..cf743de458 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -2015,7 +2015,7 @@ namespace OpenSim.Region.Environment.Scenes { if (grp == null) return; - if (grp.RootPart == null) + if (grp.IsDeleted) return; if (grp.RootPart.DIE_AT_EDGE) @@ -2116,7 +2116,7 @@ namespace OpenSim.Region.Environment.Scenes } else { - if (grp.RootPart != null) + if (!grp.IsDeleted) { if (grp.RootPart.PhysActor != null) { @@ -2688,7 +2688,7 @@ namespace OpenSim.Region.Environment.Scenes SceneObjectPart part = GetSceneObjectPart(localID); if (part != null) // It is a prim { - if (part.ParentGroup != null && part.ParentGroup.RootPart != null) // Valid + if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid { if (part.ParentGroup.RootPart != part) // Child part return; @@ -4200,7 +4200,7 @@ namespace OpenSim.Region.Environment.Scenes if (part == null || part.ParentGroup == null) return; - if (part.ParentGroup.RootPart == null) + if (part.ParentGroup.IsDeleted) return; part = part.ParentGroup.RootPart; @@ -4366,7 +4366,7 @@ namespace OpenSim.Region.Environment.Scenes { SceneObjectGroup grp = (SceneObjectGroup)obj; - if (grp.RootPart != null) + if (!grp.IsDeleted) { if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) { diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 0af2ad2647..36b4e10785 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -1035,9 +1035,6 @@ namespace OpenSim.Region.Environment.Scenes public void DeleteGroup(bool silent) { // We need to keep track of this state in case this group is still queued for backup. - // FIXME: This is a poor temporary solution, since it still leaves plenty of scope for race - // conditions where a user deletes an entity while it is being stored. Really, the update - // code needs a redesign. m_isDeleted = true; DetachFromBackup(); @@ -1063,9 +1060,6 @@ namespace OpenSim.Region.Environment.Scenes } } } - - m_rootPart = null; - m_parts.Clear(); } } @@ -1228,7 +1222,7 @@ namespace OpenSim.Region.Environment.Scenes // Since this is the top of the section of call stack for backing up a particular scene object, don't let // any exception propogate upwards. - if (RootPart == null || UUID == UUID.Zero) + if (IsDeleted || UUID == UUID.Zero) { // DetachFromBackup(); return; @@ -1932,8 +1926,8 @@ namespace OpenSim.Region.Environment.Scenes } m_scene.UnlinkSceneObject(objectGroup.UUID, true); - objectGroup.Children.Clear(); - objectGroup.m_rootPart = null; +// objectGroup.Children.Clear(); +// objectGroup.m_rootPart = null; // TODO Deleting the original group object may cause problems later on if they have already // made it into the update queue. However, sending out updates for those parts is now @@ -2803,6 +2797,7 @@ namespace OpenSim.Region.Environment.Scenes } } } + public float GetMass() { float retmass = 0f; @@ -2815,11 +2810,12 @@ namespace OpenSim.Region.Environment.Scenes } return retmass; } + public void CheckSculptAndLoad() { lock (m_parts) { - if (RootPart != null) + if (!IsDeleted) { if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == 0) { diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index a02840cc77..74fa72532b 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -492,7 +492,7 @@ namespace OpenSim.Region.Environment.Scenes StoreUndoState(); m_offsetPosition = value; - if (ParentGroup != null && ParentGroup.RootPart != null) + if (ParentGroup != null && !ParentGroup.IsDeleted) { if (_parentID != 0 && PhysActor != null) { @@ -1326,7 +1326,7 @@ if (m_shape != null) { { if (m_parentGroup == null) return false; - if (m_parentGroup.RootPart == null) + if (m_parentGroup.IsDeleted) return false; return m_parentGroup.RootPart.DIE_AT_EDGE; @@ -1604,7 +1604,7 @@ if (m_shape != null) { } if (m_parentGroup == null) return; - if (m_parentGroup.RootPart == null) + if (m_parentGroup.IsDeleted) return; if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0) @@ -2251,7 +2251,7 @@ if (m_shape != null) { { if (m_parentGroup == null) return; - if (m_parentGroup.RootPart == null) + if (m_parentGroup.IsDeleted) return; m_parentGroup.RootPart.DIE_AT_EDGE = p; @@ -3022,7 +3022,7 @@ if (m_shape != null) { DoPhysicsPropertyUpdate(UsePhysics, false); if (m_parentGroup != null) { - if (m_parentGroup.RootPart != null) + if (!m_parentGroup.IsDeleted) { if (LocalId == m_parentGroup.RootPart.LocalId) { @@ -3070,7 +3070,7 @@ if (m_shape != null) { DoPhysicsPropertyUpdate(UsePhysics, true); if (m_parentGroup != null) { - if (m_parentGroup.RootPart != null) + if (!m_parentGroup.IsDeleted) { if (LocalId == m_parentGroup.RootPart.LocalId) { @@ -3086,7 +3086,7 @@ if (m_shape != null) { DoPhysicsPropertyUpdate(UsePhysics, false); if (m_parentGroup != null) { - if (m_parentGroup.RootPart != null) + if (!m_parentGroup.IsDeleted) { if (LocalId == m_parentGroup.RootPart.LocalId) { @@ -3341,7 +3341,7 @@ if (m_shape != null) { public void SendTerseUpdateToClient(IClientAPI remoteClient) { - if (ParentGroup == null || ParentGroup.RootPart == null) + if (ParentGroup == null || ParentGroup.IsDeleted) return; Vector3 lPos = OffsetPosition; diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index c91027ce6e..935c51b891 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -637,8 +637,10 @@ namespace OpenSim.Region.Environment.Scenes while (m_partsUpdateQueue.Count > 0) { SceneObjectPart part = m_partsUpdateQueue.Dequeue(); - if (part.ParentGroup == null || part.ParentGroup.RootPart == null) + + if (part.ParentGroup == null || part.ParentGroup.IsDeleted) continue; + if (m_updateTimes.ContainsKey(part.UUID)) { ScenePartUpdate update = m_updateTimes[part.UUID]; @@ -2582,10 +2584,8 @@ namespace OpenSim.Region.Environment.Scenes if (gobj == null) return false; - if (gobj.RootPart == null) - { + if (gobj.IsDeleted) return false; - } } } return true; @@ -2598,7 +2598,7 @@ namespace OpenSim.Region.Environment.Scenes // Validate foreach (SceneObjectGroup gobj in m_attachments) { - if (gobj == null || gobj.RootPart == null) + if (gobj == null || gobj.IsDeleted) return false; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b189ffdcb3..f8e9e96a87 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1145,7 +1145,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { // TODO: this needs to trigger a persistance save as well - if (part == null || part.ParentGroup == null || part.ParentGroup.RootPart == null) + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; if (scale.x < 0.01 || scale.y < 0.01 || scale.z < 0.01) @@ -1859,7 +1859,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_host.ParentGroup != null) { - if (m_host.ParentGroup.RootPart != null) + if (!m_host.ParentGroup.IsDeleted) { if (local != 0) force *= llGetRot(); @@ -1877,7 +1877,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_host.ParentGroup != null) { - if (m_host.ParentGroup.RootPart != null) + if (!m_host.ParentGroup.IsDeleted) { PhysicsVector tmpForce = m_host.ParentGroup.RootPart.GetForce(); force.x = tmpForce.X; @@ -2701,7 +2701,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (m_host.ParentGroup != null) { - if (m_host.ParentGroup.RootPart != null) + if (!m_host.ParentGroup.IsDeleted) { m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy); } @@ -5473,7 +5473,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (m_host.ParentGroup != null) { - if (m_host.ParentGroup.RootPart != null) + if (!m_host.ParentGroup.IsDeleted) { m_host.ParentGroup.RootPart.SetVehicleType(type); } @@ -5488,7 +5488,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_host.ParentGroup != null) { - if (m_host.ParentGroup.RootPart != null) + if (!m_host.ParentGroup.IsDeleted) { m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value); } @@ -5502,7 +5502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (m_host.ParentGroup != null) { - if (m_host.ParentGroup.RootPart != null) + if (!m_host.ParentGroup.IsDeleted) { m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, new PhysicsVector((float)vec.x, (float)vec.y, (float)vec.z) ); @@ -5517,7 +5517,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (m_host.ParentGroup != null) { - if (m_host.ParentGroup.RootPart != null) + if (!m_host.ParentGroup.IsDeleted) { m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, Rot2Quaternion(rot));