From 38cfc9366ce264d2aeb6409df48be7cecc348952 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 25 Jan 2010 21:51:58 +0000
Subject: Fix a problem where llDie() calls were sometimes leaving dead objects
behind.
When an object was deleted, the remove script instance call was aggregating the scripting events as normal.
This would queue a full update of the prim before the viewer was notifed of the deletion of that prim (QuitPacket)
On some occasions, the QuitPacket would be sent before the full update was dequeued and sent.
In principle, you would think that a viewer would ignore updates for deleted prims. But it appears that in the Linden viewer (1.23.5),
a prim update that arrives after the prim was deleted instead makes the deleted prim persist in the viewer. Such prims have no properties
and cannot be removed from the viewer except by a relog.
This change stops the prim event aggregation call if it's being deleted anyway, hence removing the spurious viewer-confusing update.
---
.../Region/Framework/Interfaces/IEntityInventory.cs | 12 ++++++++++--
OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 4 +++-
OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++++++--
.../Framework/Scenes/SceneObjectGroup.Inventory.cs | 8 ++++++--
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 12 +++++++++++-
.../Framework/Scenes/SceneObjectPartInventory.cs | 21 ++++++++++++++++-----
6 files changed, 52 insertions(+), 13 deletions(-)
(limited to 'OpenSim/Region/Framework')
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index 67395fa..eeb5102 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -77,7 +77,11 @@ namespace OpenSim.Region.Framework.Interfaces
///
/// Stop all the scripts in this entity.
///
- void RemoveScriptInstances();
+ ///
+ /// Should be true if these scripts are being removed because the scene
+ /// object is being deleted. This will prevent spurious updates to the client.
+ ///
+ void RemoveScriptInstances(bool sceneObjectBeingDeleted);
///
/// Start a script which is in this entity's inventory.
@@ -103,7 +107,11 @@ namespace OpenSim.Region.Framework.Interfaces
/// Stop a script which is in this prim's inventory.
///
///
- void RemoveScriptInstance(UUID itemId);
+ ///
+ /// Should be true if these scripts are being removed because the scene
+ /// object is being deleted. This will prevent spurious updates to the client.
+ ///
+ void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted);
///
/// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 3044017..11754ea 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -256,7 +256,7 @@ namespace OpenSim.Region.Framework.Scenes
if (isScriptRunning)
{
- part.Inventory.RemoveScriptInstance(item.ItemID);
+ part.Inventory.RemoveScriptInstance(item.ItemID, false);
}
// Update item with new asset
@@ -855,8 +855,10 @@ namespace OpenSim.Region.Framework.Scenes
if (item.Type == 10)
{
+ part.RemoveScriptEvents(itemID);
EventManager.TriggerRemoveScript(localID, itemID);
}
+
group.RemoveInventoryItem(localID, itemID);
part.GetProperties(remoteClient);
}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 234554e..4da05cf 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1009,7 +1009,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (ent is SceneObjectGroup)
{
- ((SceneObjectGroup) ent).RemoveScriptInstances();
+ ((SceneObjectGroup) ent).RemoveScriptInstances(false);
}
}
}
@@ -1884,13 +1884,15 @@ namespace OpenSim.Region.Framework.Scenes
/// Suppress broadcasting changes to other clients.
public void DeleteSceneObject(SceneObjectGroup group, bool silent)
{
+// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
+
//SceneObjectPart rootPart = group.GetChildPart(group.UUID);
// Serialise calls to RemoveScriptInstances to avoid
// deadlocking on m_parts inside SceneObjectGroup
lock (m_deleting_scene_object)
{
- group.RemoveScriptInstances();
+ group.RemoveScriptInstances(true);
}
foreach (SceneObjectPart part in group.Children.Values)
@@ -1918,6 +1920,8 @@ namespace OpenSim.Region.Framework.Scenes
}
group.DeleteGroup(silent);
+
+// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
}
///
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 5a06bdb..71354b4 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -74,13 +74,17 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Stop the scripts contained in all the prims in this group
///
- public void RemoveScriptInstances()
+ ///
+ /// Should be true if these scripts are being removed because the scene
+ /// object is being deleted. This will prevent spurious updates to the client.
+ ///
+ public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
{
lock (m_parts)
{
foreach (SceneObjectPart part in m_parts.Values)
{
- part.Inventory.RemoveScriptInstances();
+ part.Inventory.RemoveScriptInstances(sceneObjectBeingDeleted);
}
}
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 56b2f13..a5296eb 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -2479,7 +2479,7 @@ namespace OpenSim.Region.Framework.Scenes
//m_log.Debug("prev: " + prevflag.ToString() + " curr: " + Flags.ToString());
//ScheduleFullUpdate();
}
-
+
public void RemoveScriptEvents(UUID scriptid)
{
lock (m_scriptEvents)
@@ -2533,6 +2533,8 @@ namespace OpenSim.Region.Framework.Scenes
///
public void ScheduleFullUpdate()
{
+// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId);
+
if (m_parentGroup != null)
{
m_parentGroup.QueueForUpdateCheck();
@@ -4042,6 +4044,8 @@ namespace OpenSim.Region.Framework.Scenes
if (m_parentGroup == null)
{
+// m_log.DebugFormat(
+// "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents() since m_parentGroup == null", Name, LocalId);
ScheduleFullUpdate();
return;
}
@@ -4058,9 +4062,15 @@ namespace OpenSim.Region.Framework.Scenes
LocalFlags=(PrimFlags)objectflagupdate;
if (m_parentGroup != null && m_parentGroup.RootPart == this)
+ {
m_parentGroup.aggregateScriptEvents();
+ }
else
+ {
+// m_log.DebugFormat(
+// "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents()", Name, LocalId);
ScheduleFullUpdate();
+ }
}
public int registerTargetWaypoint(Vector3 target, float tolerance)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index eb7f5ff..5f13278 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -230,7 +230,11 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Stop all the scripts in this prim.
///
- public void RemoveScriptInstances()
+ ///
+ /// Should be true if these scripts are being removed because the scene
+ /// object is being deleted. This will prevent spurious updates to the client.
+ ///
+ public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
{
lock (Items)
{
@@ -238,8 +242,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if ((int)InventoryType.LSL == item.InvType)
{
- RemoveScriptInstance(item.ItemID);
- m_part.RemoveScriptEvents(item.ItemID);
+ RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
}
}
}
@@ -388,10 +391,17 @@ namespace OpenSim.Region.Framework.Scenes
/// Stop a script which is in this prim's inventory.
///
///
- public void RemoveScriptInstance(UUID itemId)
+ ///
+ /// Should be true if this script is being removed because the scene
+ /// object is being deleted. This will prevent spurious updates to the client.
+ ///
+ public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
{
if (m_items.ContainsKey(itemId))
{
+ if (!sceneObjectBeingDeleted)
+ m_part.RemoveScriptEvents(itemId);
+
m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemId);
m_part.ParentGroup.AddActiveScriptCount(-1);
}
@@ -465,7 +475,7 @@ namespace OpenSim.Region.Framework.Scenes
if (i.Name == item.Name)
{
if (i.InvType == (int)InventoryType.LSL)
- RemoveScriptInstance(i.ItemID);
+ RemoveScriptInstance(i.ItemID, false);
RemoveInventoryItem(i.ItemID);
break;
@@ -613,6 +623,7 @@ namespace OpenSim.Region.Framework.Scenes
int type = m_items[itemID].InvType;
if (type == 10) // Script
{
+ m_part.RemoveScriptEvents(itemID);
m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
}
m_items.Remove(itemID);
--
cgit v1.1