aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-01-16 02:07:43 +0000
committerJustin Clark-Casey (justincc)2013-01-16 02:07:43 +0000
commit0963ece25bdef16852f5fd8ae4515a2f05d8b6e4 (patch)
treef95a3eef3e94df4408d555a30cd62bce629623f2 /OpenSim/Region/ScriptEngine/Shared
parentRevert "Implement co-operative script termination if termination comes during... (diff)
downloadopensim-SC_OLD-0963ece25bdef16852f5fd8ae4515a2f05d8b6e4.zip
opensim-SC_OLD-0963ece25bdef16852f5fd8ae4515a2f05d8b6e4.tar.gz
opensim-SC_OLD-0963ece25bdef16852f5fd8ae4515a2f05d8b6e4.tar.bz2
opensim-SC_OLD-0963ece25bdef16852f5fd8ae4515a2f05d8b6e4.tar.xz
Implement co-operative script termination if termination comes during a script wait event (llSleep(), etc.)
This makes use of EventWaitHandles since various web references indicate that Thread.Interrupt() can also cause runtime instability. If co-op termination is enabled, then termination sets the wait handle instead of waiting for a timeout before possibly aborting the thread. This allows the script to cleanly terminate if it's in a llSleep/LL function delay or the next time it enters such a wait without any timeout period. Co-op termination is not yet testable since checking for termination request within loops that never trigger a wait is not yet implemented. This commit, unlike 1b5c41c, passes the wait handle as an extra parameter through IScript.Initialize() instead of passing IScriptInstance itself.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs35
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs18
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs54
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs157
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs16
14 files changed, 291 insertions, 49 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 44072c6..d47fd6b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -83,10 +83,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
83 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 83 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
84 { 84 {
85 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 85 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
86
86 protected IScriptEngine m_ScriptEngine; 87 protected IScriptEngine m_ScriptEngine;
87 protected SceneObjectPart m_host; 88 protected SceneObjectPart m_host;
88 89
89 /// <summary> 90 /// <summary>
91 /// Used for script sleeps when we are using co-operative script termination.
92 /// </summary>
93 /// <remarks>null if co-operative script termination is not active</remarks>
94 EventWaitHandle m_coopSleepHandle;
95
96 /// <summary>
90 /// The item that hosts this script 97 /// The item that hosts this script
91 /// </summary> 98 /// </summary>
92 protected TaskInventoryItem m_item; 99 protected TaskInventoryItem m_item;
@@ -110,13 +117,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
110 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 117 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
111 protected ISoundModule m_SoundModule = null; 118 protected ISoundModule m_SoundModule = null;
112 119
113 public void Initialize(IScriptInstance scriptInstance) 120 public void Initialize(
121 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle)
114 { 122 {
115 m_ScriptEngine = scriptInstance.Engine; 123 m_ScriptEngine = scriptEngine;
116 m_host = scriptInstance.Part; 124 m_host = host;
117 m_item = scriptInstance.ScriptTask; 125 m_item = item;
126 m_coopSleepHandle = coopSleepHandle;
118 127
119 LoadLimits(); // read script limits from config. 128 LoadConfig();
120 129
121 m_TransferModule = 130 m_TransferModule =
122 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); 131 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>();
@@ -129,7 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
129 /// <summary> 138 /// <summary>
130 /// Load configuration items that affect script, object and run-time behavior. */ 139 /// Load configuration items that affect script, object and run-time behavior. */
131 /// </summary> 140 /// </summary>
132 private void LoadLimits() 141 private void LoadConfig()
133 { 142 {
134 m_ScriptDelayFactor = 143 m_ScriptDelayFactor =
135 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 144 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -175,7 +184,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
175 delay = (int)((float)delay * m_ScriptDelayFactor); 184 delay = (int)((float)delay * m_ScriptDelayFactor);
176 if (delay == 0) 185 if (delay == 0)
177 return; 186 return;
178 System.Threading.Thread.Sleep(delay); 187
188 Sleep(delay);
189 }
190
191 protected virtual void Sleep(int delay)
192 {
193 if (m_coopSleepHandle == null)
194 System.Threading.Thread.Sleep(delay);
195 else if (m_coopSleepHandle.WaitOne(delay))
196 throw new ScriptCoopStopException();
179 } 197 }
180 198
181 public Scene World 199 public Scene World
@@ -2914,7 +2932,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2914 { 2932 {
2915// m_log.Info("llSleep snoozing " + sec + "s."); 2933// m_log.Info("llSleep snoozing " + sec + "s.");
2916 m_host.AddScriptLPS(1); 2934 m_host.AddScriptLPS(1);
2917 Thread.Sleep((int)(sec * 1000)); 2935
2936 Sleep((int)(sec * 1000));
2918 } 2937 }
2919 2938
2920 public LSL_Float llGetMass() 2939 public LSL_Float llGetMass()
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index 071c60e..a08ccc8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -30,6 +30,7 @@ using System.Reflection;
30using System.Collections; 30using System.Collections;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
33using System.Threading;
33using OpenMetaverse; 34using OpenMetaverse;
34using Nini.Config; 35using Nini.Config;
35using OpenSim; 36using OpenSim;
@@ -61,10 +62,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
61 internal bool m_LSFunctionsEnabled = false; 62 internal bool m_LSFunctionsEnabled = false;
62 internal IScriptModuleComms m_comms = null; 63 internal IScriptModuleComms m_comms = null;
63 64
64 public void Initialize(IScriptInstance scriptInstance) 65 public void Initialize(
66 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle)
65 { 67 {
66 m_ScriptEngine = scriptInstance.Engine; 68 m_ScriptEngine = scriptEngine;
67 m_host = scriptInstance.Part; 69 m_host = host;
68 70
69 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) 71 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false))
70 m_LSFunctionsEnabled = true; 72 m_LSFunctionsEnabled = true;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index cbc69aa..981499e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -30,6 +30,7 @@ using System.Reflection;
30using System.Collections; 30using System.Collections;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
33using System.Threading;
33using OpenMetaverse; 34using OpenMetaverse;
34using Nini.Config; 35using Nini.Config;
35using OpenSim; 36using OpenSim;
@@ -61,11 +62,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
61 internal bool m_MODFunctionsEnabled = false; 62 internal bool m_MODFunctionsEnabled = false;
62 internal IScriptModuleComms m_comms = null; 63 internal IScriptModuleComms m_comms = null;
63 64
64 public void Initialize(IScriptInstance scriptInstance) 65 public void Initialize(
66 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle)
65 { 67 {
66 m_ScriptEngine = scriptInstance.Engine; 68 m_ScriptEngine = scriptEngine;
67 m_host = scriptInstance.Part; 69 m_host = host;
68 m_item = scriptInstance.ScriptTask; 70 m_item = item;
69 71
70 if (m_ScriptEngine.Config.GetBoolean("AllowMODFunctions", false)) 72 if (m_ScriptEngine.Config.GetBoolean("AllowMODFunctions", false))
71 m_MODFunctionsEnabled = true; 73 m_MODFunctionsEnabled = true;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 33ae5f0..25635ff 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -142,11 +142,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
142 142
143 protected IUrlModule m_UrlModule = null; 143 protected IUrlModule m_UrlModule = null;
144 144
145 public void Initialize(IScriptInstance scriptInstance) 145 public void Initialize(
146 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle)
146 { 147 {
147 m_ScriptEngine = scriptInstance.Engine; 148 m_ScriptEngine = scriptEngine;
148 m_host = scriptInstance.Part; 149 m_host = host;
149 m_item = scriptInstance.ScriptTask; 150 m_item = item;
150 151
151 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 152 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
152 153
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 5a58f73..e02d35e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -81,6 +81,24 @@ namespace OpenSim.Region.ScriptEngine.Shared
81 } 81 }
82 } 82 }
83 83
84 /// <summary>
85 /// Used to signal when the script is stopping in co-operation with the script engine
86 /// (instead of through Thread.Abort()).
87 /// </summary>
88 [Serializable]
89 public class ScriptCoopStopException : Exception
90 {
91 public ScriptCoopStopException()
92 {
93 }
94
95 protected ScriptCoopStopException(
96 SerializationInfo info,
97 StreamingContext context)
98 {
99 }
100 }
101
84 public class DetectParams 102 public class DetectParams
85 { 103 {
86 public const int AGENT = 1; 104 public const int AGENT = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index a2ff51b..75aea2b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -200,6 +200,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
200 200
201 public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute; 201 public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute;
202 202
203 private bool m_coopTermination;
204
205 private EventWaitHandle m_coopSleepHandle;
206
203 public void ClearQueue() 207 public void ClearQueue()
204 { 208 {
205 m_TimerQueued = false; 209 m_TimerQueued = false;
@@ -233,6 +237,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
233 m_postOnRez = postOnRez; 237 m_postOnRez = postOnRez;
234 m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; 238 m_AttachedAvatar = Part.ParentGroup.AttachedAvatar;
235 m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; 239 m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID;
240
241 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op")
242 {
243 m_coopTermination = true;
244 m_coopSleepHandle = new AutoResetEvent(false);
245 }
236 } 246 }
237 247
238 /// <summary> 248 /// <summary>
@@ -251,7 +261,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
251 foreach (string api in am.GetApis()) 261 foreach (string api in am.GetApis())
252 { 262 {
253 m_Apis[api] = am.CreateApi(api); 263 m_Apis[api] = am.CreateApi(api);
254 m_Apis[api].Initialize(this); 264 m_Apis[api].Initialize(Engine, Part, ScriptTask, m_coopSleepHandle);
255 } 265 }
256 266
257 try 267 try
@@ -532,9 +542,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
532 } 542 }
533 543
534 // Wait for the current event to complete. 544 // Wait for the current event to complete.
535 if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000))) 545 if (!m_InSelfDelete)
536 { 546 {
537 return true; 547 if (!m_coopTermination)
548 {
549 // If we're not co-operative terminating then try and wait for the event to complete before stopping
550 if (workItem.Wait(new TimeSpan((long)timeout * 100000)))
551 return true;
552 }
553 else
554 {
555 m_log.DebugFormat(
556 "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}",
557 ScriptName, ItemID, PrimName, ObjectID);
558
559 // This will terminate the event on next handle check by the script.
560 m_coopSleepHandle.Set();
561
562 // For now, we will wait forever since the event should always cleanly terminate once LSL loop
563 // checking is implemented. May want to allow a shorter timeout option later.
564 if (workItem.Wait(TimeSpan.MaxValue))
565 {
566 m_log.DebugFormat(
567 "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}",
568 ScriptName, ItemID, PrimName, ObjectID);
569
570 return true;
571 }
572 }
538 } 573 }
539 574
540 lock (EventQueue) 575 lock (EventQueue)
@@ -547,6 +582,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
547 582
548 // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then 583 // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then
549 // forcibly abort the work item (this aborts the underlying thread). 584 // forcibly abort the work item (this aborts the underlying thread).
585 // Co-operative termination should never reach this point.
550 if (!m_InSelfDelete) 586 if (!m_InSelfDelete)
551 { 587 {
552 m_log.DebugFormat( 588 m_log.DebugFormat(
@@ -786,7 +822,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
786 m_InEvent = false; 822 m_InEvent = false;
787 m_CurrentEvent = String.Empty; 823 m_CurrentEvent = String.Empty;
788 824
789 if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) 825 if ((!(e is TargetInvocationException)
826 || (!(e.InnerException is SelfDeleteException)
827 && !(e.InnerException is ScriptDeleteException)
828 && !(e.InnerException is ScriptCoopStopException)))
829 && !(e is ThreadAbortException))
790 { 830 {
791 try 831 try
792 { 832 {
@@ -834,6 +874,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
834 m_InSelfDelete = true; 874 m_InSelfDelete = true;
835 Part.Inventory.RemoveInventoryItem(ItemID); 875 Part.Inventory.RemoveInventoryItem(ItemID);
836 } 876 }
877 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException))
878 {
879 m_log.DebugFormat(
880 "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.",
881 PrimName, ScriptName, data.EventName, State);
882 }
837 } 883 }
838 } 884 }
839 } 885 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
new file mode 100644
index 0000000..8c3e9e0
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
@@ -0,0 +1,157 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Threading;
31using Nini.Config;
32using NUnit.Framework;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Region.CoreModules.Scripting.WorldComm;
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.ScriptEngine.XEngine;
39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41
42namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
43{
44 /// <summary>
45 /// Test that co-operative script thread termination is working correctly.
46 /// </summary>
47 [TestFixture]
48 public class CoopTerminationTests : OpenSimTestCase
49 {
50 private TestScene m_scene;
51 private OpenSim.Region.ScriptEngine.XEngine.XEngine m_xEngine;
52
53 private AutoResetEvent m_chatEvent = new AutoResetEvent(false);
54 private AutoResetEvent m_stoppedEvent = new AutoResetEvent(false);
55
56 private OSChatMessage m_osChatMessageReceived;
57
58 [TestFixtureSetUp]
59 public void Init()
60 {
61 //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin");
62// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory);
63 m_xEngine = new OpenSim.Region.ScriptEngine.XEngine.XEngine();
64
65 IniConfigSource configSource = new IniConfigSource();
66
67 IConfig startupConfig = configSource.AddConfig("Startup");
68 startupConfig.Set("DefaultScriptEngine", "XEngine");
69
70 IConfig xEngineConfig = configSource.AddConfig("XEngine");
71 xEngineConfig.Set("Enabled", "true");
72 xEngineConfig.Set("StartDelay", "0");
73
74 // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call
75 // to AssemblyResolver.OnAssemblyResolve fails.
76 xEngineConfig.Set("AppDomainLoading", "false");
77
78 xEngineConfig.Set("ScriptStopStrategy", "co-op");
79
80 m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource);
81 SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine);
82 m_scene.StartScripts();
83 }
84
85 /// <summary>
86 /// Test co-operative termination on derez of an object containing a script with a long-running event.
87 /// </summary>
88 /// <remarks>
89 /// TODO: Actually compiling the script is incidental to this test. Really want a way to compile test scripts
90 /// within the build itself.
91 /// </remarks>
92 [Test]
93 public void TestStopOnLongSleep()
94 {
95 TestHelpers.InMethod();
96// TestHelpers.EnableLogging();
97
98 UUID userId = TestHelpers.ParseTail(0x1);
99// UUID objectId = TestHelpers.ParseTail(0x100);
100// UUID itemId = TestHelpers.ParseTail(0x3);
101 string itemName = "TestStopOnObjectDerezLongSleep() Item";
102
103 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStopOnObjectDerezLongSleep", 0x100);
104 m_scene.AddNewSceneObject(so, true);
105
106 InventoryItemBase itemTemplate = new InventoryItemBase();
107// itemTemplate.ID = itemId;
108 itemTemplate.Name = itemName;
109 itemTemplate.Folder = so.UUID;
110 itemTemplate.InvType = (int)InventoryType.LSL;
111
112 m_scene.EventManager.OnChatFromWorld += OnChatFromWorld;
113
114 SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate,
115@"default
116{
117 state_entry()
118 {
119 llSay(0, ""Thin Lizzy"");
120 llSleep(60);
121 }
122}");
123
124 TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
125
126 // Wait for the script to start the event before we try stopping it.
127 m_chatEvent.WaitOne(60000);
128
129 Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message);
130
131 // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script
132 // executes llSay() but has not started the sleep before we try to stop it.
133 Thread.Sleep(1000);
134
135 // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually
136 // stopped. This kind of multi-threading is far from ideal in a regression test.
137 new Thread(() => { m_xEngine.StopScript(rezzedItem.ItemID); m_stoppedEvent.Set(); }).Start();
138
139 if (!m_stoppedEvent.WaitOne(30000))
140 Assert.Fail("Script did not co-operatively stop.");
141
142 bool running;
143 TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
144 Assert.That(
145 SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True);
146 Assert.That(running, Is.False);
147 }
148
149 private void OnChatFromWorld(object sender, OSChatMessage oscm)
150 {
151// Console.WriteLine("Got chat [{0}]", oscm.Message);
152
153 m_osChatMessageReceived = oscm;
154 m_chatEvent.Set();
155 }
156 }
157} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs
index 36c7582..6dd6c17 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
94 TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); 94 TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId);
95 95
96 LSL_Api api = new LSL_Api(); 96 LSL_Api api = new LSL_Api();
97 api.Initialize(new ScriptInstance(m_engine, so1.RootPart, null, 0, false, int.MaxValue)); 97 api.Initialize(m_engine, so1.RootPart, null, null);
98 98
99 // Create a second object 99 // Create a second object
100 SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100); 100 SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100);
@@ -127,7 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
127 SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10); 127 SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10);
128 m_scene.AddSceneObject(so1); 128 m_scene.AddSceneObject(so1);
129 LSL_Api api = new LSL_Api(); 129 LSL_Api api = new LSL_Api();
130 api.Initialize(new ScriptInstance(m_engine, so1.RootPart, null, 0, false, int.MaxValue)); 130 api.Initialize(m_engine, so1.RootPart, null, null);
131 131
132 // Create an object embedded inside the first 132 // Create an object embedded inside the first
133 UUID itemId = TestHelpers.ParseTail(0x20); 133 UUID itemId = TestHelpers.ParseTail(0x20);
@@ -137,7 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
137 SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100); 137 SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100);
138 m_scene.AddSceneObject(so2); 138 m_scene.AddSceneObject(so2);
139 LSL_Api api2 = new LSL_Api(); 139 LSL_Api api2 = new LSL_Api();
140 api2.Initialize(new ScriptInstance(m_engine, so2.RootPart, null, 0, false, int.MaxValue)); 140 api2.Initialize(m_engine, so2.RootPart, null, null);
141 141
142 // *** Firstly, we test where llAllowInventoryDrop() has not been called. *** 142 // *** Firstly, we test where llAllowInventoryDrop() has not been called. ***
143 api.llGiveInventory(so2.UUID.ToString(), inventoryItemName); 143 api.llGiveInventory(so2.UUID.ToString(), inventoryItemName);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs
index 5121344..5b57bbe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs
@@ -105,7 +105,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
105 m_scene.AddSceneObject(grp2); 105 m_scene.AddSceneObject(grp2);
106 106
107 LSL_Api apiGrp1 = new LSL_Api(); 107 LSL_Api apiGrp1 = new LSL_Api();
108 apiGrp1.Initialize(new ScriptInstance(m_engine, grp1.RootPart, grp1Item, 0, false, int.MaxValue)); 108 apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item, null);
109 109
110 apiGrp1.llCreateLink(grp2.UUID.ToString(), ScriptBaseClass.TRUE); 110 apiGrp1.llCreateLink(grp2.UUID.ToString(), ScriptBaseClass.TRUE);
111 111
@@ -132,7 +132,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
132 grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 132 grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
133 133
134 LSL_Api apiGrp1 = new LSL_Api(); 134 LSL_Api apiGrp1 = new LSL_Api();
135 apiGrp1.Initialize(new ScriptInstance(m_engine, grp1.RootPart, grp1Item, 0, false, int.MaxValue)); 135 apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item, null);
136 136
137 apiGrp1.llBreakLink(2); 137 apiGrp1.llBreakLink(2);
138 138
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs
index 28e5831..60de5cb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
68 engine.AddRegion(scene); 68 engine.AddRegion(scene);
69 69
70 m_lslApi = new LSL_Api(); 70 m_lslApi = new LSL_Api();
71 m_lslApi.Initialize(new ScriptInstance(engine, part, null, 0, false, int.MaxValue)); 71 m_lslApi.Initialize(engine, part, null, null);
72 } 72 }
73 73
74 [Test] 74 [Test]
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
index 48c2465..e97ae06 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
67 engine.AddRegion(scene); 67 engine.AddRegion(scene);
68 68
69 m_lslApi = new LSL_Api(); 69 m_lslApi = new LSL_Api();
70 m_lslApi.Initialize(new ScriptInstance(engine, part, null, 0, false, int.MaxValue)); 70 m_lslApi.Initialize(engine, part, null, null);
71 } 71 }
72 72
73 [Test] 73 [Test]
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
index 5164d4e..c88bad5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
94 m_scene.AddSceneObject(so); 94 m_scene.AddSceneObject(so);
95 95
96 OSSL_Api osslApi = new OSSL_Api(); 96 OSSL_Api osslApi = new OSSL_Api();
97 osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); 97 osslApi.Initialize(m_engine, part, null, null);
98 98
99 string notecardName = "appearanceNc"; 99 string notecardName = "appearanceNc";
100 100
@@ -135,7 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
135 m_scene.AddSceneObject(so); 135 m_scene.AddSceneObject(so);
136 136
137 OSSL_Api osslApi = new OSSL_Api(); 137 OSSL_Api osslApi = new OSSL_Api();
138 osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); 138 osslApi.Initialize(m_engine, part, null, null);
139 139
140 string notecardName = "appearanceNc"; 140 string notecardName = "appearanceNc";
141 141
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
index e7b3319..b2803a1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
@@ -99,10 +99,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
99 SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); 99 SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID);
100 TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); 100 TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart);
101 101
102 ScriptInstance si = new ScriptInstance(m_engine, inWorldObj.RootPart, scriptItem, 0, false, int.MaxValue); 102 new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null);
103 new LSL_Api().Initialize(si);
104 OSSL_Api osslApi = new OSSL_Api(); 103 OSSL_Api osslApi = new OSSL_Api();
105 osslApi.Initialize(si); 104 osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null);
106 105
107// SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ua1.PrincipalID); 106// SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ua1.PrincipalID);
108 107
@@ -146,10 +145,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
146 SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); 145 SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID);
147 TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); 146 TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart);
148 147
149 ScriptInstance si = new ScriptInstance(m_engine, inWorldObj.RootPart, scriptItem, 0, false, int.MaxValue); 148 new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null);
150 new LSL_Api().Initialize(si);
151 OSSL_Api osslApi = new OSSL_Api(); 149 OSSL_Api osslApi = new OSSL_Api();
152 osslApi.Initialize(si); 150 osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null);
153 151
154 // Create an object embedded inside the first 152 // Create an object embedded inside the first
155 TaskInventoryHelpers.AddNotecard( 153 TaskInventoryHelpers.AddNotecard(
@@ -195,10 +193,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
195 SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); 193 SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID);
196 TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); 194 TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart);
197 195
198 ScriptInstance si = new ScriptInstance(m_engine, inWorldObj.RootPart, scriptItem, 0, false, int.MaxValue); 196 new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null);
199 new LSL_Api().Initialize(si);
200 OSSL_Api osslApi = new OSSL_Api(); 197 OSSL_Api osslApi = new OSSL_Api();
201 osslApi.Initialize(si); 198 osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null);
202 199
203 // Create an object embedded inside the first 200 // Create an object embedded inside the first
204 TaskInventoryHelpers.AddSceneObject( 201 TaskInventoryHelpers.AddSceneObject(
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
index 584f44f..1f8a6e5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
@@ -100,7 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
100 m_scene.AddSceneObject(so); 100 m_scene.AddSceneObject(so);
101 101
102 OSSL_Api osslApi = new OSSL_Api(); 102 OSSL_Api osslApi = new OSSL_Api();
103 osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); 103 osslApi.Initialize(m_engine, part, null, null);
104 104
105 string notecardName = "appearanceNc"; 105 string notecardName = "appearanceNc";
106 osslApi.osOwnerSaveAppearance(notecardName); 106 osslApi.osOwnerSaveAppearance(notecardName);
@@ -126,7 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
126 m_scene.AddSceneObject(so); 126 m_scene.AddSceneObject(so);
127 127
128 OSSL_Api osslApi = new OSSL_Api(); 128 OSSL_Api osslApi = new OSSL_Api();
129 osslApi.Initialize(new ScriptInstance(m_engine, so.RootPart, null, 0, false, int.MaxValue)); 129 osslApi.Initialize(m_engine, so.RootPart, null, null);
130 130
131 bool gotExpectedException = false; 131 bool gotExpectedException = false;
132 try 132 try
@@ -161,7 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
161 m_scene.AddSceneObject(so); 161 m_scene.AddSceneObject(so);
162 162
163 OSSL_Api osslApi = new OSSL_Api(); 163 OSSL_Api osslApi = new OSSL_Api();
164 osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); 164 osslApi.Initialize(m_engine, part, null, null);
165 165
166 string notecardName = "appearanceNc"; 166 string notecardName = "appearanceNc";
167 osslApi.osOwnerSaveAppearance(notecardName); 167 osslApi.osOwnerSaveAppearance(notecardName);
@@ -195,7 +195,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
195 m_scene.AddSceneObject(so); 195 m_scene.AddSceneObject(so);
196 196
197 OSSL_Api osslApi = new OSSL_Api(); 197 OSSL_Api osslApi = new OSSL_Api();
198 osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); 198 osslApi.Initialize(m_engine, part, null, null);
199 199
200 osslApi.osOwnerSaveAppearance(firstAppearanceNcName); 200 osslApi.osOwnerSaveAppearance(firstAppearanceNcName);
201 201
@@ -233,7 +233,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
233 m_scene.AddSceneObject(so); 233 m_scene.AddSceneObject(so);
234 234
235 OSSL_Api osslApi = new OSSL_Api(); 235 OSSL_Api osslApi = new OSSL_Api();
236 osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); 236 osslApi.Initialize(m_engine, part, null, null);
237 237
238 osslApi.osOwnerSaveAppearance(firstAppearanceNcName); 238 osslApi.osOwnerSaveAppearance(firstAppearanceNcName);
239 239
@@ -285,10 +285,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
285 m_scene.AddSceneObject(otherSo); 285 m_scene.AddSceneObject(otherSo);
286 286
287 OSSL_Api osslApi = new OSSL_Api(); 287 OSSL_Api osslApi = new OSSL_Api();
288 osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); 288 osslApi.Initialize(m_engine, part, null, null);
289 289
290 OSSL_Api otherOsslApi = new OSSL_Api(); 290 OSSL_Api otherOsslApi = new OSSL_Api();
291 otherOsslApi.Initialize(new ScriptInstance(m_engine, otherPart, null, 0, false, int.MaxValue)); 291 otherOsslApi.Initialize(m_engine, otherPart, null, null);
292 292
293 string notecardName = "appearanceNc"; 293 string notecardName = "appearanceNc";
294 osslApi.osOwnerSaveAppearance(notecardName); 294 osslApi.osOwnerSaveAppearance(notecardName);
@@ -332,7 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
332 m_scene.AddSceneObject(so); 332 m_scene.AddSceneObject(so);
333 333
334 OSSL_Api osslApi = new OSSL_Api(); 334 OSSL_Api osslApi = new OSSL_Api();
335 osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); 335 osslApi.Initialize(m_engine, part, null, null);
336 336
337 string notecardName = "appearanceNc"; 337 string notecardName = "appearanceNc";
338 osslApi.osOwnerSaveAppearance(notecardName); 338 osslApi.osOwnerSaveAppearance(notecardName);