* 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);
x = m_inventoryDeletes.Dequeue();
if (x.objectGroup.RootPart != null)
if (!x.objectGroup.IsDeleted)
{
try
{

View File

@ -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;

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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;

View File

@ -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;
}

View File

@ -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));