* 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
0.6.1-post-fixes
Justin Clarke Casey 2008-11-17 15:40:27 +00:00
parent dd37fbb137
commit d54b6608a7
7 changed files with 35 additions and 39 deletions

View File

@ -126,7 +126,7 @@ namespace OpenSim.Region.Environment.Scenes
"[SCENE]: Sending deleted object to user's inventory, {0} item(s) remaining.", left); "[SCENE]: Sending deleted object to user's inventory, {0} item(s) remaining.", left);
x = m_inventoryDeletes.Dequeue(); x = m_inventoryDeletes.Dequeue();
if (x.objectGroup.RootPart != null) if (!x.objectGroup.IsDeleted)
{ {
try try
{ {

View File

@ -1552,7 +1552,7 @@ namespace OpenSim.Region.Environment.Scenes
if (part == null) if (part == null)
return; return;
if (part.ParentGroup == null || part.ParentGroup.RootPart == null) if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
return; return;
// Can't delete child prims // Can't delete child prims
@ -2379,7 +2379,7 @@ namespace OpenSim.Region.Environment.Scenes
public UUID RezSingleAttachment(SceneObjectGroup att, public UUID RezSingleAttachment(SceneObjectGroup att,
IClientAPI remoteClient, UUID itemID, uint AttachmentPt) IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{ {
if (att.RootPart != null) if (!att.IsDeleted)
AttachmentPt = att.RootPart.AttachmentPoint; AttachmentPt = att.RootPart.AttachmentPoint;
ScenePresence presence; ScenePresence presence;

View File

@ -2015,7 +2015,7 @@ namespace OpenSim.Region.Environment.Scenes
{ {
if (grp == null) if (grp == null)
return; return;
if (grp.RootPart == null) if (grp.IsDeleted)
return; return;
if (grp.RootPart.DIE_AT_EDGE) if (grp.RootPart.DIE_AT_EDGE)
@ -2116,7 +2116,7 @@ namespace OpenSim.Region.Environment.Scenes
} }
else else
{ {
if (grp.RootPart != null) if (!grp.IsDeleted)
{ {
if (grp.RootPart.PhysActor != null) if (grp.RootPart.PhysActor != null)
{ {
@ -2688,7 +2688,7 @@ namespace OpenSim.Region.Environment.Scenes
SceneObjectPart part = GetSceneObjectPart(localID); SceneObjectPart part = GetSceneObjectPart(localID);
if (part != null) // It is a prim 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 if (part.ParentGroup.RootPart != part) // Child part
return; return;
@ -4200,7 +4200,7 @@ namespace OpenSim.Region.Environment.Scenes
if (part == null || part.ParentGroup == null) if (part == null || part.ParentGroup == null)
return; return;
if (part.ParentGroup.RootPart == null) if (part.ParentGroup.IsDeleted)
return; return;
part = part.ParentGroup.RootPart; part = part.ParentGroup.RootPart;
@ -4366,7 +4366,7 @@ namespace OpenSim.Region.Environment.Scenes
{ {
SceneObjectGroup grp = (SceneObjectGroup)obj; SceneObjectGroup grp = (SceneObjectGroup)obj;
if (grp.RootPart != null) if (!grp.IsDeleted)
{ {
if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
{ {

View File

@ -1035,9 +1035,6 @@ namespace OpenSim.Region.Environment.Scenes
public void DeleteGroup(bool silent) public void DeleteGroup(bool silent)
{ {
// We need to keep track of this state in case this group is still queued for backup. // 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; m_isDeleted = true;
DetachFromBackup(); 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 // 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. // any exception propogate upwards.
if (RootPart == null || UUID == UUID.Zero) if (IsDeleted || UUID == UUID.Zero)
{ {
// DetachFromBackup(); // DetachFromBackup();
return; return;
@ -1932,8 +1926,8 @@ namespace OpenSim.Region.Environment.Scenes
} }
m_scene.UnlinkSceneObject(objectGroup.UUID, true); m_scene.UnlinkSceneObject(objectGroup.UUID, true);
objectGroup.Children.Clear(); // objectGroup.Children.Clear();
objectGroup.m_rootPart = null; // objectGroup.m_rootPart = null;
// TODO Deleting the original group object may cause problems later on if they have already // 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 // 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() public float GetMass()
{ {
float retmass = 0f; float retmass = 0f;
@ -2815,11 +2810,12 @@ namespace OpenSim.Region.Environment.Scenes
} }
return retmass; return retmass;
} }
public void CheckSculptAndLoad() public void CheckSculptAndLoad()
{ {
lock (m_parts) lock (m_parts)
{ {
if (RootPart != null) if (!IsDeleted)
{ {
if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == 0) if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == 0)
{ {

View File

@ -492,7 +492,7 @@ namespace OpenSim.Region.Environment.Scenes
StoreUndoState(); StoreUndoState();
m_offsetPosition = value; m_offsetPosition = value;
if (ParentGroup != null && ParentGroup.RootPart != null) if (ParentGroup != null && !ParentGroup.IsDeleted)
{ {
if (_parentID != 0 && PhysActor != null) if (_parentID != 0 && PhysActor != null)
{ {
@ -1326,7 +1326,7 @@ if (m_shape != null) {
{ {
if (m_parentGroup == null) if (m_parentGroup == null)
return false; return false;
if (m_parentGroup.RootPart == null) if (m_parentGroup.IsDeleted)
return false; return false;
return m_parentGroup.RootPart.DIE_AT_EDGE; return m_parentGroup.RootPart.DIE_AT_EDGE;
@ -1604,7 +1604,7 @@ if (m_shape != null) {
} }
if (m_parentGroup == null) if (m_parentGroup == null)
return; return;
if (m_parentGroup.RootPart == null) if (m_parentGroup.IsDeleted)
return; return;
if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0) if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0)
@ -2251,7 +2251,7 @@ if (m_shape != null) {
{ {
if (m_parentGroup == null) if (m_parentGroup == null)
return; return;
if (m_parentGroup.RootPart == null) if (m_parentGroup.IsDeleted)
return; return;
m_parentGroup.RootPart.DIE_AT_EDGE = p; m_parentGroup.RootPart.DIE_AT_EDGE = p;
@ -3022,7 +3022,7 @@ if (m_shape != null) {
DoPhysicsPropertyUpdate(UsePhysics, false); DoPhysicsPropertyUpdate(UsePhysics, false);
if (m_parentGroup != null) if (m_parentGroup != null)
{ {
if (m_parentGroup.RootPart != null) if (!m_parentGroup.IsDeleted)
{ {
if (LocalId == m_parentGroup.RootPart.LocalId) if (LocalId == m_parentGroup.RootPart.LocalId)
{ {
@ -3070,7 +3070,7 @@ if (m_shape != null) {
DoPhysicsPropertyUpdate(UsePhysics, true); DoPhysicsPropertyUpdate(UsePhysics, true);
if (m_parentGroup != null) if (m_parentGroup != null)
{ {
if (m_parentGroup.RootPart != null) if (!m_parentGroup.IsDeleted)
{ {
if (LocalId == m_parentGroup.RootPart.LocalId) if (LocalId == m_parentGroup.RootPart.LocalId)
{ {
@ -3086,7 +3086,7 @@ if (m_shape != null) {
DoPhysicsPropertyUpdate(UsePhysics, false); DoPhysicsPropertyUpdate(UsePhysics, false);
if (m_parentGroup != null) if (m_parentGroup != null)
{ {
if (m_parentGroup.RootPart != null) if (!m_parentGroup.IsDeleted)
{ {
if (LocalId == m_parentGroup.RootPart.LocalId) if (LocalId == m_parentGroup.RootPart.LocalId)
{ {
@ -3341,7 +3341,7 @@ if (m_shape != null) {
public void SendTerseUpdateToClient(IClientAPI remoteClient) public void SendTerseUpdateToClient(IClientAPI remoteClient)
{ {
if (ParentGroup == null || ParentGroup.RootPart == null) if (ParentGroup == null || ParentGroup.IsDeleted)
return; return;
Vector3 lPos = OffsetPosition; Vector3 lPos = OffsetPosition;

View File

@ -637,8 +637,10 @@ namespace OpenSim.Region.Environment.Scenes
while (m_partsUpdateQueue.Count > 0) while (m_partsUpdateQueue.Count > 0)
{ {
SceneObjectPart part = m_partsUpdateQueue.Dequeue(); SceneObjectPart part = m_partsUpdateQueue.Dequeue();
if (part.ParentGroup == null || part.ParentGroup.RootPart == null)
if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
continue; continue;
if (m_updateTimes.ContainsKey(part.UUID)) if (m_updateTimes.ContainsKey(part.UUID))
{ {
ScenePartUpdate update = m_updateTimes[part.UUID]; ScenePartUpdate update = m_updateTimes[part.UUID];
@ -2582,12 +2584,10 @@ namespace OpenSim.Region.Environment.Scenes
if (gobj == null) if (gobj == null)
return false; return false;
if (gobj.RootPart == null) if (gobj.IsDeleted)
{
return false; return false;
} }
} }
}
return true; return true;
} }
@ -2598,7 +2598,7 @@ namespace OpenSim.Region.Environment.Scenes
// Validate // Validate
foreach (SceneObjectGroup gobj in m_attachments) foreach (SceneObjectGroup gobj in m_attachments)
{ {
if (gobj == null || gobj.RootPart == null) if (gobj == null || gobj.IsDeleted)
return false; return false;
} }

View File

@ -1145,7 +1145,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
// TODO: this needs to trigger a persistance save as well // 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; return;
if (scale.x < 0.01 || scale.y < 0.01 || scale.z < 0.01) 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 != null)
{ {
if (m_host.ParentGroup.RootPart != null) if (!m_host.ParentGroup.IsDeleted)
{ {
if (local != 0) if (local != 0)
force *= llGetRot(); force *= llGetRot();
@ -1877,7 +1877,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (m_host.ParentGroup != null) if (m_host.ParentGroup != null)
{ {
if (m_host.ParentGroup.RootPart != null) if (!m_host.ParentGroup.IsDeleted)
{ {
PhysicsVector tmpForce = m_host.ParentGroup.RootPart.GetForce(); PhysicsVector tmpForce = m_host.ParentGroup.RootPart.GetForce();
force.x = tmpForce.X; force.x = tmpForce.X;
@ -2701,7 +2701,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
if (m_host.ParentGroup != null) if (m_host.ParentGroup != null)
{ {
if (m_host.ParentGroup.RootPart != null) if (!m_host.ParentGroup.IsDeleted)
{ {
m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy); m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy);
} }
@ -5473,7 +5473,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
if (m_host.ParentGroup != null) if (m_host.ParentGroup != null)
{ {
if (m_host.ParentGroup.RootPart != null) if (!m_host.ParentGroup.IsDeleted)
{ {
m_host.ParentGroup.RootPart.SetVehicleType(type); 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 != null)
{ {
if (m_host.ParentGroup.RootPart != null) if (!m_host.ParentGroup.IsDeleted)
{ {
m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value); m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value);
} }
@ -5502,7 +5502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
if (m_host.ParentGroup != null) if (m_host.ParentGroup != null)
{ {
if (m_host.ParentGroup.RootPart != null) if (!m_host.ParentGroup.IsDeleted)
{ {
m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, m_host.ParentGroup.RootPart.SetVehicleVectorParam(param,
new PhysicsVector((float)vec.x, (float)vec.y, (float)vec.z) ); 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); m_host.AddScriptLPS(1);
if (m_host.ParentGroup != null) if (m_host.ParentGroup != null)
{ {
if (m_host.ParentGroup.RootPart != null) if (!m_host.ParentGroup.IsDeleted)
{ {
m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, m_host.ParentGroup.RootPart.SetVehicleRotationParam(param,
Rot2Quaternion(rot)); Rot2Quaternion(rot));