diff options
author | Justin Clark-Casey (justincc) | 2012-07-10 22:41:11 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-07-10 22:41:11 +0100 |
commit | f3134b5cf688af9b824880e0221072b24d22f33e (patch) | |
tree | 94ac27ba4fd2f7f0700cc626005d20d7c6465881 | |
parent | If a script is being stopped manually, then give the scriptpool thread 1 seco... (diff) | |
download | opensim-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.
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> |