aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-07-10 22:41:11 +0100
committerJustin Clark-Casey (justincc)2012-07-10 22:41:11 +0100
commitf3134b5cf688af9b824880e0221072b24d22f33e (patch)
tree94ac27ba4fd2f7f0700cc626005d20d7c6465881
parentIf a script is being stopped manually, then give the scriptpool thread 1 seco... (diff)
downloadopensim-SC-f3134b5cf688af9b824880e0221072b24d22f33e.zip
opensim-SC-f3134b5cf688af9b824880e0221072b24d22f33e.tar.gz
opensim-SC-f3134b5cf688af9b824880e0221072b24d22f33e.tar.bz2
opensim-SC-f3134b5cf688af9b824880e0221072b24d22f33e.tar.xz
When an attachment is detached to inv or derezzed, stop the scripts, update the known item with script state still in the script engine and then remove the scripts.
This is to fix a regression starting from 5301648 where attachments had to start being deleted before persistence in order to avoid race conditions with hud update threads.
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs20
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityInventory.cs15
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs59
5 files changed, 110 insertions, 13 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index eccf7a6..efab6ed 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -211,16 +211,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
211 211
212 lock (sp.AttachmentsSyncLock) 212 lock (sp.AttachmentsSyncLock)
213 { 213 {
214 foreach (SceneObjectGroup grp in sp.GetAttachments()) 214 foreach (SceneObjectGroup so in sp.GetAttachments())
215 { 215 {
216 grp.Scene.DeleteSceneObject(grp, false); 216 // We can only remove the script instances from the script engine after we've retrieved their xml state
217 // when we update the attachment item.
218 m_scene.DeleteSceneObject(so, false, false);
217 219
218 if (saveChanged || saveAllScripted) 220 if (saveChanged || saveAllScripted)
219 { 221 {
220 grp.IsAttachment = false; 222 so.IsAttachment = false;
221 grp.AbsolutePosition = grp.RootPart.AttachedPos; 223 so.AbsolutePosition = so.RootPart.AttachedPos;
222 UpdateKnownItem(sp, grp, saveAllScripted); 224 UpdateKnownItem(sp, so, saveAllScripted);
223 } 225 }
226
227 so.RemoveScriptInstances(true);
224 } 228 }
225 229
226 sp.ClearAttachments(); 230 sp.ClearAttachments();
@@ -682,7 +686,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
682 686
683 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); 687 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero);
684 sp.RemoveAttachment(so); 688 sp.RemoveAttachment(so);
685 m_scene.DeleteSceneObject(so, false); 689
690 // We can only remove the script instances from the script engine after we've retrieved their xml state
691 // when we update the attachment item.
692 m_scene.DeleteSceneObject(so, false, false);
686 693
687 // Prepare sog for storage 694 // Prepare sog for storage
688 so.AttachedAvatar = UUID.Zero; 695 so.AttachedAvatar = UUID.Zero;
@@ -691,6 +698,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
691 so.AbsolutePosition = so.RootPart.AttachedPos; 698 so.AbsolutePosition = so.RootPart.AttachedPos;
692 699
693 UpdateKnownItem(sp, so, true); 700 UpdateKnownItem(sp, so, true);
701 so.RemoveScriptInstances(true);
694 } 702 }
695 703
696 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 704 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index 1c9bdce..8d62847 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -92,7 +92,7 @@ namespace OpenSim.Region.Framework.Interfaces
92 void ResumeScripts(); 92 void ResumeScripts();
93 93
94 /// <summary> 94 /// <summary>
95 /// Stop all the scripts in this entity. 95 /// Stop and remove all the scripts in this entity from the scene.
96 /// </summary> 96 /// </summary>
97 /// <param name="sceneObjectBeingDeleted"> 97 /// <param name="sceneObjectBeingDeleted">
98 /// Should be true if these scripts are being removed because the scene 98 /// Should be true if these scripts are being removed because the scene
@@ -101,6 +101,11 @@ namespace OpenSim.Region.Framework.Interfaces
101 void RemoveScriptInstances(bool sceneObjectBeingDeleted); 101 void RemoveScriptInstances(bool sceneObjectBeingDeleted);
102 102
103 /// <summary> 103 /// <summary>
104 /// Stop all the scripts in this entity.
105 /// </summary>
106 void StopScriptInstances();
107
108 /// <summary>
104 /// Start a script which is in this entity's inventory. 109 /// Start a script which is in this entity's inventory.
105 /// </summary> 110 /// </summary>
106 /// <param name="item"></param> 111 /// <param name="item"></param>
@@ -129,7 +134,7 @@ namespace OpenSim.Region.Framework.Interfaces
129 bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource); 134 bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource);
130 135
131 /// <summary> 136 /// <summary>
132 /// Stop a script which is in this prim's inventory. 137 /// Stop and remove a script which is in this prim's inventory from the scene.
133 /// </summary> 138 /// </summary>
134 /// <param name="itemId"></param> 139 /// <param name="itemId"></param>
135 /// <param name="sceneObjectBeingDeleted"> 140 /// <param name="sceneObjectBeingDeleted">
@@ -139,6 +144,12 @@ namespace OpenSim.Region.Framework.Interfaces
139 void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted); 144 void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted);
140 145
141 /// <summary> 146 /// <summary>
147 /// Stop a script which is in this prim's inventory.
148 /// </summary>
149 /// <param name="itemId"></param>
150 void StopScriptInstance(UUID itemId);
151
152 /// <summary>
142 /// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative 153 /// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative
143 /// name is chosen. 154 /// name is chosen.
144 /// </summary> 155 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index ec911a5..25223b9 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2183,13 +2183,30 @@ namespace OpenSim.Region.Framework.Scenes
2183 /// <summary> 2183 /// <summary>
2184 /// Synchronously delete the given object from the scene. 2184 /// Synchronously delete the given object from the scene.
2185 /// </summary> 2185 /// </summary>
2186 /// <remarks>
2187 /// Scripts are also removed.
2188 /// </remarks>
2186 /// <param name="group">Object Id</param> 2189 /// <param name="group">Object Id</param>
2187 /// <param name="silent">Suppress broadcasting changes to other clients.</param> 2190 /// <param name="silent">Suppress broadcasting changes to other clients.</param>
2188 public void DeleteSceneObject(SceneObjectGroup group, bool silent) 2191 public void DeleteSceneObject(SceneObjectGroup group, bool silent)
2192 {
2193 DeleteSceneObject(group, silent, true);
2194 }
2195
2196 /// <summary>
2197 /// Synchronously delete the given object from the scene.
2198 /// </summary>
2199 /// <param name="group">Object Id</param>
2200 /// <param name="silent">Suppress broadcasting changes to other clients.</param>
2201 /// <param name="removeScripts">If true, then scripts are removed. If false, then they are only stopped.</para>
2202 public void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts)
2189 { 2203 {
2190// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); 2204// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
2191 2205
2192 group.RemoveScriptInstances(true); 2206 if (removeScripts)
2207 group.RemoveScriptInstances(true);
2208 else
2209 group.StopScriptInstances();
2193 2210
2194 SceneObjectPart[] partList = group.Parts; 2211 SceneObjectPart[] partList = group.Parts;
2195 2212
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 2866b54..ddf5da0 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -79,7 +79,7 @@ namespace OpenSim.Region.Framework.Scenes
79 } 79 }
80 80
81 /// <summary> 81 /// <summary>
82 /// Stop the scripts contained in all the prims in this group 82 /// Stop and remove the scripts contained in all the prims in this group
83 /// </summary> 83 /// </summary>
84 /// <param name="sceneObjectBeingDeleted"> 84 /// <param name="sceneObjectBeingDeleted">
85 /// Should be true if these scripts are being removed because the scene 85 /// Should be true if these scripts are being removed because the scene
@@ -93,6 +93,14 @@ namespace OpenSim.Region.Framework.Scenes
93 } 93 }
94 94
95 /// <summary> 95 /// <summary>
96 /// Stop the scripts contained in all the prims in this group
97 /// </summary>
98 public void StopScriptInstances()
99 {
100 Array.ForEach<SceneObjectPart>(m_parts.GetArray(), p => p.Inventory.StopScriptInstances());
101 }
102
103 /// <summary>
96 /// Add an inventory item from a user's inventory to a prim in this scene object. 104 /// Add an inventory item from a user's inventory to a prim in this scene object.
97 /// </summary> 105 /// </summary>
98 /// <param name="agentID">The agent adding the item.</param> 106 /// <param name="agentID">The agent adding the item.</param>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 866311a..cf2ed1a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -280,7 +280,7 @@ namespace OpenSim.Region.Framework.Scenes
280 } 280 }
281 281
282 /// <summary> 282 /// <summary>
283 /// Stop all the scripts in this prim. 283 /// Stop and remove all the scripts in this prim.
284 /// </summary> 284 /// </summary>
285 /// <param name="sceneObjectBeingDeleted"> 285 /// <param name="sceneObjectBeingDeleted">
286 /// Should be true if these scripts are being removed because the scene 286 /// Should be true if these scripts are being removed because the scene
@@ -294,6 +294,14 @@ namespace OpenSim.Region.Framework.Scenes
294 } 294 }
295 295
296 /// <summary> 296 /// <summary>
297 /// Stop all the scripts in this prim.
298 /// </summary>
299 public void StopScriptInstances()
300 {
301 GetInventoryItems(InventoryType.LSL).ForEach(i => StopScriptInstance(i));
302 }
303
304 /// <summary>
297 /// Start a script which is in this prim's inventory. 305 /// Start a script which is in this prim's inventory.
298 /// </summary> 306 /// </summary>
299 /// <param name="item"></param> 307 /// <param name="item"></param>
@@ -443,7 +451,7 @@ namespace OpenSim.Region.Framework.Scenes
443 } 451 }
444 452
445 /// <summary> 453 /// <summary>
446 /// Stop a script which is in this prim's inventory. 454 /// Stop and remove a script which is in this prim's inventory.
447 /// </summary> 455 /// </summary>
448 /// <param name="itemId"></param> 456 /// <param name="itemId"></param>
449 /// <param name="sceneObjectBeingDeleted"> 457 /// <param name="sceneObjectBeingDeleted">
@@ -470,7 +478,36 @@ namespace OpenSim.Region.Framework.Scenes
470 } 478 }
471 else 479 else
472 { 480 {
473 m_log.ErrorFormat( 481 m_log.WarnFormat(
482 "[PRIM INVENTORY]: " +
483 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
484 itemId, m_part.Name, m_part.UUID,
485 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
486 }
487 }
488
489 /// <summary>
490 /// Stop a script which is in this prim's inventory.
491 /// </summary>
492 /// <param name="itemId"></param>
493 /// <param name="sceneObjectBeingDeleted">
494 /// Should be true if this script is being removed because the scene
495 /// object is being deleted. This will prevent spurious updates to the client.
496 /// </param>
497 public void StopScriptInstance(UUID itemId)
498 {
499 TaskInventoryItem scriptItem;
500
501 lock (m_items)
502 m_items.TryGetValue(itemId, out scriptItem);
503
504 if (scriptItem != null)
505 {
506 StopScriptInstance(scriptItem);
507 }
508 else
509 {
510 m_log.WarnFormat(
474 "[PRIM INVENTORY]: " + 511 "[PRIM INVENTORY]: " +
475 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 512 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
476 itemId, m_part.Name, m_part.UUID, 513 itemId, m_part.Name, m_part.UUID,
@@ -479,6 +516,22 @@ namespace OpenSim.Region.Framework.Scenes
479 } 516 }
480 517
481 /// <summary> 518 /// <summary>
519 /// Stop a script which is in this prim's inventory.
520 /// </summary>
521 /// <param name="itemId"></param>
522 /// <param name="sceneObjectBeingDeleted">
523 /// Should be true if this script is being removed because the scene
524 /// object is being deleted. This will prevent spurious updates to the client.
525 /// </param>
526 public void StopScriptInstance(TaskInventoryItem item)
527 {
528 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID);
529
530 // At the moment, even stopped scripts are counted as active, which is probably wrong.
531// m_part.ParentGroup.AddActiveScriptCount(-1);
532 }
533
534 /// <summary>
482 /// Check if the inventory holds an item with a given name. 535 /// Check if the inventory holds an item with a given name.
483 /// </summary> 536 /// </summary>
484 /// <param name="name"></param> 537 /// <param name="name"></param>