diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine')
8 files changed, 205 insertions, 118 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs b/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs index f4211c8..80d9e2a 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs | |||
@@ -44,7 +44,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine.ScriptBase | |||
44 | /// <summary> | 44 | /// <summary> |
45 | /// Used for script sleeps when we are using co-operative script termination. | 45 | /// Used for script sleeps when we are using co-operative script termination. |
46 | /// </summary> | 46 | /// </summary> |
47 | /// <remarks>null if co-operative script termination is not active</remarks> | 47 | /// <remarks>null if co-operative script termination is not active</remarks> |
48 | WaitHandle m_coopSleepHandle; | 48 | WaitHandle m_coopSleepHandle; |
49 | 49 | ||
50 | public XEngineScriptBase(WaitHandle coopSleepHandle) : base() | 50 | public XEngineScriptBase(WaitHandle coopSleepHandle) : base() |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs index 0ff2da3..55a77bc 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs | |||
@@ -79,7 +79,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
79 | } | 79 | } |
80 | 80 | ||
81 | /// <summary> | 81 | /// <summary> |
82 | /// When an object gets paid by an avatar and generates the paid event, | 82 | /// When an object gets paid by an avatar and generates the paid event, |
83 | /// this will pipe it to the script engine | 83 | /// this will pipe it to the script engine |
84 | /// </summary> | 84 | /// </summary> |
85 | /// <param name="objectID">Object ID that got paid</param> | 85 | /// <param name="objectID">Object ID that got paid</param> |
@@ -244,7 +244,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
244 | { | 244 | { |
245 | DetectParams d = new DetectParams(); | 245 | DetectParams d = new DetectParams(); |
246 | d.Key =detobj.keyUUID; | 246 | d.Key =detobj.keyUUID; |
247 | d.Populate(myScriptEngine.World); | 247 | d.Populate(myScriptEngine.World, detobj); |
248 | d.LinkNum = detobj.linkNumber; // do it here since currently linknum is collided part | ||
248 | det.Add(d); | 249 | det.Add(d); |
249 | } | 250 | } |
250 | 251 | ||
@@ -263,8 +264,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
263 | foreach (DetectedObject detobj in col.Colliders) | 264 | foreach (DetectedObject detobj in col.Colliders) |
264 | { | 265 | { |
265 | DetectParams d = new DetectParams(); | 266 | DetectParams d = new DetectParams(); |
266 | d.Key =detobj.keyUUID; | 267 | d.Populate(myScriptEngine.World, detobj); |
267 | d.Populate(myScriptEngine.World); | ||
268 | det.Add(d); | 268 | det.Add(d); |
269 | } | 269 | } |
270 | 270 | ||
@@ -282,8 +282,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
282 | foreach (DetectedObject detobj in col.Colliders) | 282 | foreach (DetectedObject detobj in col.Colliders) |
283 | { | 283 | { |
284 | DetectParams d = new DetectParams(); | 284 | DetectParams d = new DetectParams(); |
285 | d.Key =detobj.keyUUID; | 285 | d.Populate(myScriptEngine.World, detobj); |
286 | d.Populate(myScriptEngine.World); | ||
287 | det.Add(d); | 286 | det.Add(d); |
288 | } | 287 | } |
289 | 288 | ||
@@ -301,8 +300,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
301 | foreach (DetectedObject detobj in col.Colliders) | 300 | foreach (DetectedObject detobj in col.Colliders) |
302 | { | 301 | { |
303 | DetectParams d = new DetectParams(); | 302 | DetectParams d = new DetectParams(); |
304 | d.Position = detobj.posVector; | 303 | d.Populate(myScriptEngine.World, detobj); |
305 | d.Populate(myScriptEngine.World); | ||
306 | det.Add(d); | 304 | det.Add(d); |
307 | myScriptEngine.PostObjectEvent(localID, new EventParams( | 305 | myScriptEngine.PostObjectEvent(localID, new EventParams( |
308 | "land_collision_start", | 306 | "land_collision_start", |
@@ -319,8 +317,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
319 | foreach (DetectedObject detobj in col.Colliders) | 317 | foreach (DetectedObject detobj in col.Colliders) |
320 | { | 318 | { |
321 | DetectParams d = new DetectParams(); | 319 | DetectParams d = new DetectParams(); |
322 | d.Position = detobj.posVector; | 320 | d.Populate(myScriptEngine.World,detobj); |
323 | d.Populate(myScriptEngine.World); | ||
324 | det.Add(d); | 321 | det.Add(d); |
325 | myScriptEngine.PostObjectEvent(localID, new EventParams( | 322 | myScriptEngine.PostObjectEvent(localID, new EventParams( |
326 | "land_collision", | 323 | "land_collision", |
@@ -336,8 +333,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
336 | foreach (DetectedObject detobj in col.Colliders) | 333 | foreach (DetectedObject detobj in col.Colliders) |
337 | { | 334 | { |
338 | DetectParams d = new DetectParams(); | 335 | DetectParams d = new DetectParams(); |
339 | d.Position = detobj.posVector; | 336 | d.Populate(myScriptEngine.World,detobj); |
340 | d.Populate(myScriptEngine.World); | ||
341 | det.Add(d); | 337 | det.Add(d); |
342 | myScriptEngine.PostObjectEvent(localID, new EventParams( | 338 | myScriptEngine.PostObjectEvent(localID, new EventParams( |
343 | "land_collision_end", | 339 | "land_collision_end", |
@@ -412,10 +408,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
412 | 408 | ||
413 | public void attach(uint localID, UUID itemID, UUID avatar) | 409 | public void attach(uint localID, UUID itemID, UUID avatar) |
414 | { | 410 | { |
415 | myScriptEngine.PostObjectEvent(localID, new EventParams( | 411 | SceneObjectGroup grp = myScriptEngine.World.GetSceneObjectGroup(localID); |
412 | if(grp == null) | ||
413 | return; | ||
414 | |||
415 | foreach(SceneObjectPart part in grp.Parts) | ||
416 | { | ||
417 | myScriptEngine.PostObjectEvent(part.LocalId, new EventParams( | ||
416 | "attach",new object[] { | 418 | "attach",new object[] { |
417 | new LSL_Types.LSLString(avatar.ToString()) }, | 419 | new LSL_Types.LSLString(avatar.ToString()) }, |
418 | new DetectParams[0])); | 420 | new DetectParams[0])); |
421 | } | ||
419 | } | 422 | } |
420 | 423 | ||
421 | // dataserver: not handled here | 424 | // dataserver: not handled here |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs index 665929d..b3fedcb 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs | |||
@@ -3,7 +3,7 @@ using System.Runtime.CompilerServices; | |||
3 | using System.Runtime.InteropServices; | 3 | using System.Runtime.InteropServices; |
4 | using Mono.Addins; | 4 | using Mono.Addins; |
5 | 5 | ||
6 | // General Information about an assembly is controlled through the following | 6 | // General Information about an assembly is controlled through the following |
7 | // set of attributes. Change these attribute values to modify the information | 7 | // set of attributes. Change these attribute values to modify the information |
8 | // associated with an assembly. | 8 | // associated with an assembly. |
9 | [assembly: AssemblyTitle("OpenSim.Region.ScriptEngine.XEngine")] | 9 | [assembly: AssemblyTitle("OpenSim.Region.ScriptEngine.XEngine")] |
@@ -15,8 +15,8 @@ using Mono.Addins; | |||
15 | [assembly: AssemblyTrademark("")] | 15 | [assembly: AssemblyTrademark("")] |
16 | [assembly: AssemblyCulture("")] | 16 | [assembly: AssemblyCulture("")] |
17 | 17 | ||
18 | // Setting ComVisible to false makes the types in this assembly not visible | 18 | // Setting ComVisible to false makes the types in this assembly not visible |
19 | // to COM components. If you need to access a type in this assembly from | 19 | // to COM components. If you need to access a type in this assembly from |
20 | // COM, set the ComVisible attribute to true on that type. | 20 | // COM, set the ComVisible attribute to true on that type. |
21 | [assembly: ComVisible(false)] | 21 | [assembly: ComVisible(false)] |
22 | 22 | ||
@@ -26,11 +26,11 @@ using Mono.Addins; | |||
26 | // Version information for an assembly consists of the following four values: | 26 | // Version information for an assembly consists of the following four values: |
27 | // | 27 | // |
28 | // Major Version | 28 | // Major Version |
29 | // Minor Version | 29 | // Minor Version |
30 | // Build Number | 30 | // Build Number |
31 | // Revision | 31 | // Revision |
32 | // | 32 | // |
33 | [assembly: AssemblyVersion("0.8.3.*")] | 33 | [assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] |
34 | 34 | ||
35 | [assembly: Addin("OpenSim.Region.ScriptEngine.XEngine", OpenSim.VersionInfo.VersionNumber)] | 35 | [assembly: Addin("OpenSim.Region.ScriptEngine.XEngine", OpenSim.VersionInfo.VersionNumber)] |
36 | [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] | 36 | [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs index 878e571..71ef0ac 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs | |||
@@ -58,7 +58,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine.Tests | |||
58 | m_xEngine = new XEngine(); | 58 | m_xEngine = new XEngine(); |
59 | 59 | ||
60 | IniConfigSource configSource = new IniConfigSource(); | 60 | IniConfigSource configSource = new IniConfigSource(); |
61 | 61 | ||
62 | IConfig startupConfig = configSource.AddConfig("Startup"); | 62 | IConfig startupConfig = configSource.AddConfig("Startup"); |
63 | startupConfig.Set("DefaultScriptEngine", "XEngine"); | 63 | startupConfig.Set("DefaultScriptEngine", "XEngine"); |
64 | 64 | ||
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineCrossingTests.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineCrossingTests.cs index 587695f..477059f 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineCrossingTests.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineCrossingTests.cs | |||
@@ -85,6 +85,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine.Tests | |||
85 | 85 | ||
86 | IConfig startupConfig = configSource.AddConfig("Startup"); | 86 | IConfig startupConfig = configSource.AddConfig("Startup"); |
87 | startupConfig.Set("DefaultScriptEngine", "XEngine"); | 87 | startupConfig.Set("DefaultScriptEngine", "XEngine"); |
88 | startupConfig.Set("TrustBinaries", "true"); | ||
88 | 89 | ||
89 | IConfig xEngineConfig = configSource.AddConfig("XEngine"); | 90 | IConfig xEngineConfig = configSource.AddConfig("XEngine"); |
90 | xEngineConfig.Set("Enabled", "true"); | 91 | xEngineConfig.Set("Enabled", "true"); |
@@ -111,10 +112,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine.Tests | |||
111 | SceneObjectGroup soSceneA = SceneHelpers.AddSceneObject(sceneA, 1, userId, "so1-", sceneObjectIdTail); | 112 | SceneObjectGroup soSceneA = SceneHelpers.AddSceneObject(sceneA, 1, userId, "so1-", sceneObjectIdTail); |
112 | soSceneA.AbsolutePosition = new Vector3(128, 10, 20); | 113 | soSceneA.AbsolutePosition = new Vector3(128, 10, 20); |
113 | 114 | ||
115 | string soSceneAName = soSceneA.Name; | ||
116 | string scriptItemSceneAName = "script1"; | ||
117 | |||
114 | // CREATE SCRIPT TODO | 118 | // CREATE SCRIPT TODO |
115 | InventoryItemBase scriptItemSceneA = new InventoryItemBase(); | 119 | InventoryItemBase scriptItemSceneA = new InventoryItemBase(); |
116 | // itemTemplate.ID = itemId; | 120 | // itemTemplate.ID = itemId; |
117 | scriptItemSceneA.Name = "script1"; | 121 | scriptItemSceneA.Name = scriptItemSceneAName; |
118 | scriptItemSceneA.Folder = soSceneA.UUID; | 122 | scriptItemSceneA.Folder = soSceneA.UUID; |
119 | scriptItemSceneA.InvType = (int)InventoryType.LSL; | 123 | scriptItemSceneA.InvType = (int)InventoryType.LSL; |
120 | 124 | ||
@@ -122,11 +126,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine.Tests | |||
122 | OSChatMessage messageReceived = null; | 126 | OSChatMessage messageReceived = null; |
123 | sceneA.EventManager.OnChatFromWorld += (s, m) => { messageReceived = m; chatEvent.Set(); }; | 127 | sceneA.EventManager.OnChatFromWorld += (s, m) => { messageReceived = m; chatEvent.Set(); }; |
124 | 128 | ||
125 | sceneA.RezNewScript(userId, scriptItemSceneA, | 129 | sceneA.RezNewScript(userId, scriptItemSceneA, |
126 | @"integer c = 0; | 130 | @"integer c = 0; |
127 | 131 | ||
128 | default | 132 | default |
129 | { | 133 | { |
130 | state_entry() | 134 | state_entry() |
131 | { | 135 | { |
132 | llSay(0, ""Script running""); | 136 | llSay(0, ""Script running""); |
@@ -139,7 +143,7 @@ default | |||
139 | 143 | ||
140 | touch_start(integer n) | 144 | touch_start(integer n) |
141 | { | 145 | { |
142 | c = c + 1; | 146 | c = c + 1; |
143 | llSay(0, (string)c); | 147 | llSay(0, (string)c); |
144 | } | 148 | } |
145 | }"); | 149 | }"); |
@@ -147,7 +151,7 @@ default | |||
147 | chatEvent.WaitOne(60000); | 151 | chatEvent.WaitOne(60000); |
148 | 152 | ||
149 | Assert.That(messageReceived, Is.Not.Null, "No chat message received."); | 153 | Assert.That(messageReceived, Is.Not.Null, "No chat message received."); |
150 | Assert.That(messageReceived.Message, Is.EqualTo("Script running")); | 154 | Assert.That(messageReceived.Message, Is.EqualTo("Script running")); |
151 | 155 | ||
152 | { | 156 | { |
153 | // XXX: Should not be doing this so directly. Should call some variant of EventManager.touch() instead. | 157 | // XXX: Should not be doing this so directly. Should call some variant of EventManager.touch() instead. |
@@ -158,24 +162,31 @@ default | |||
158 | 162 | ||
159 | EventParams ep = new EventParams("touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, det); | 163 | EventParams ep = new EventParams("touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, det); |
160 | 164 | ||
165 | messageReceived = null; | ||
166 | chatEvent.Reset(); | ||
161 | xEngineA.PostObjectEvent(soSceneA.LocalId, ep); | 167 | xEngineA.PostObjectEvent(soSceneA.LocalId, ep); |
162 | chatEvent.WaitOne(60000); | 168 | chatEvent.WaitOne(60000); |
163 | 169 | ||
164 | Assert.That(messageReceived.Message, Is.EqualTo("1")); | 170 | Assert.That(messageReceived.Message, Is.EqualTo("1")); |
165 | } | 171 | } |
166 | 172 | ||
167 | sceneB.EventManager.OnChatFromWorld += (s, m) => { messageReceived = m; chatEvent.Set(); }; | 173 | AutoResetEvent chatEventB = new AutoResetEvent(false); |
174 | sceneB.EventManager.OnChatFromWorld += (s, m) => { messageReceived = m; chatEventB.Set(); }; | ||
168 | 175 | ||
176 | messageReceived = null; | ||
177 | chatEventB.Reset(); | ||
169 | // Cross with a negative value | 178 | // Cross with a negative value |
170 | soSceneA.AbsolutePosition = new Vector3(128, -10, 20); | 179 | soSceneA.AbsolutePosition = new Vector3(128, -10, 20); |
171 | 180 | ||
172 | chatEvent.WaitOne(60000); | 181 | chatEventB.WaitOne(60000); |
173 | Assert.That(messageReceived.Message, Is.EqualTo("Changed")); | 182 | Assert.That(messageReceived, Is.Not.Null, "No Changed message received."); |
183 | Assert.That(messageReceived.Message, Is.Not.Null, "Changed message without content"); | ||
184 | Assert.That(messageReceived.Message, Is.EqualTo("Changed")); | ||
174 | 185 | ||
175 | // TEST sending event to moved prim and output | 186 | // TEST sending event to moved prim and output |
176 | { | 187 | { |
177 | SceneObjectGroup soSceneB = sceneB.GetSceneObjectGroup(soSceneA.Name); | 188 | SceneObjectGroup soSceneB = sceneB.GetSceneObjectGroup(soSceneAName); |
178 | TaskInventoryItem scriptItemSceneB = soSceneB.RootPart.Inventory.GetInventoryItem(scriptItemSceneA.Name); | 189 | TaskInventoryItem scriptItemSceneB = soSceneB.RootPart.Inventory.GetInventoryItem(scriptItemSceneAName); |
179 | 190 | ||
180 | // XXX: Should not be doing this so directly. Should call some variant of EventManager.touch() instead. | 191 | // XXX: Should not be doing this so directly. Should call some variant of EventManager.touch() instead. |
181 | DetectParams[] det = new DetectParams[1]; | 192 | DetectParams[] det = new DetectParams[1]; |
@@ -185,10 +196,13 @@ default | |||
185 | 196 | ||
186 | EventParams ep = new EventParams("touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, det); | 197 | EventParams ep = new EventParams("touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, det); |
187 | 198 | ||
199 | Thread.Sleep(250); // wait for other change messages to pass | ||
200 | messageReceived = null; | ||
201 | chatEventB.Reset(); | ||
188 | xEngineB.PostObjectEvent(soSceneB.LocalId, ep); | 202 | xEngineB.PostObjectEvent(soSceneB.LocalId, ep); |
189 | chatEvent.WaitOne(60000); | 203 | chatEventB.WaitOne(60000); |
190 | 204 | ||
191 | Assert.That(messageReceived.Message, Is.EqualTo("2")); | 205 | Assert.That(messageReceived.Message, Is.EqualTo("2")); |
192 | } | 206 | } |
193 | } | 207 | } |
194 | } | 208 | } |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEnginePersistenceTests.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEnginePersistenceTests.cs index 2ef4058..07470d6 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEnginePersistenceTests.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEnginePersistenceTests.cs | |||
@@ -43,6 +43,7 @@ using OpenSim.Tests.Common; | |||
43 | 43 | ||
44 | namespace OpenSim.Region.ScriptEngine.Tests | 44 | namespace OpenSim.Region.ScriptEngine.Tests |
45 | { | 45 | { |
46 | /* | ||
46 | [TestFixture] | 47 | [TestFixture] |
47 | public class XEnginePersistenceTests : OpenSimTestCase | 48 | public class XEnginePersistenceTests : OpenSimTestCase |
48 | { | 49 | { |
@@ -149,4 +150,5 @@ namespace OpenSim.Region.ScriptEngine.Tests | |||
149 | scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, rezzedSo); | 150 | scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, rezzedSo); |
150 | } | 151 | } |
151 | } | 152 | } |
153 | */ | ||
152 | } \ No newline at end of file | 154 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 6df36f7..05124fc 100644..100755 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -78,7 +78,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
78 | /// A parameter to allow us to notify the log if at least one script has a compilation that is not compatible | 78 | /// A parameter to allow us to notify the log if at least one script has a compilation that is not compatible |
79 | /// with ScriptStopStrategy. | 79 | /// with ScriptStopStrategy. |
80 | /// </summary> | 80 | /// </summary> |
81 | public bool HaveNotifiedLogOfScriptStopMistmatch { get; private set; } | 81 | public bool HaveNotifiedLogOfScriptStopMismatch { get; private set; } |
82 | 82 | ||
83 | private SmartThreadPool m_ThreadPool; | 83 | private SmartThreadPool m_ThreadPool; |
84 | private int m_MaxScriptQueue; | 84 | private int m_MaxScriptQueue; |
@@ -110,6 +110,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
110 | private int m_ScriptFailCount; // Number of script fails since compile queue was last empty | 110 | private int m_ScriptFailCount; // Number of script fails since compile queue was last empty |
111 | private string m_ScriptErrorMessage; | 111 | private string m_ScriptErrorMessage; |
112 | private bool m_AppDomainLoading; | 112 | private bool m_AppDomainLoading; |
113 | private bool m_CompactMemOnLoad; | ||
113 | private Dictionary<UUID,ArrayList> m_ScriptErrors = | 114 | private Dictionary<UUID,ArrayList> m_ScriptErrors = |
114 | new Dictionary<UUID,ArrayList>(); | 115 | new Dictionary<UUID,ArrayList>(); |
115 | 116 | ||
@@ -130,9 +131,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
130 | /// It appears that if a script thread is aborted whilst it is holding ReaderWriterLockSlim (possibly the write | 131 | /// It appears that if a script thread is aborted whilst it is holding ReaderWriterLockSlim (possibly the write |
131 | /// lock) then the lock is not properly released. This causes mono 2.6, 2.10 and possibly | 132 | /// lock) then the lock is not properly released. This causes mono 2.6, 2.10 and possibly |
132 | /// later to crash, sometimes with symptoms such as a leap to 100% script usage and a vm thead dump showing | 133 | /// later to crash, sometimes with symptoms such as a leap to 100% script usage and a vm thead dump showing |
133 | /// all threads waiting on release of ReaderWriterLockSlim write thread which none of the threads listed | 134 | /// all threads waiting on release of ReaderWriterLockSlim write thread which none of the threads listed |
134 | /// actually hold. | 135 | /// actually hold. |
135 | /// | 136 | /// |
136 | /// Pausing for event completion reduces the risk of this happening. However, it may be that aborting threads | 137 | /// Pausing for event completion reduces the risk of this happening. However, it may be that aborting threads |
137 | /// is not a mono issue per se but rather a risky activity in itself in an AppDomain that is not immediately | 138 | /// is not a mono issue per se but rather a risky activity in itself in an AppDomain that is not immediately |
138 | /// shutting down. | 139 | /// shutting down. |
@@ -181,7 +182,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
181 | 182 | ||
182 | private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); | 183 | private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); |
183 | IWorkItemResult m_CurrentCompile = null; | 184 | IWorkItemResult m_CurrentCompile = null; |
184 | private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); | 185 | private Dictionary<UUID, ScriptCompileInfo> m_CompileDict = new Dictionary<UUID, ScriptCompileInfo>(); |
185 | 186 | ||
186 | private ScriptEngineConsoleCommands m_consoleCommands; | 187 | private ScriptEngineConsoleCommands m_consoleCommands; |
187 | 188 | ||
@@ -235,6 +236,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
235 | get { return m_ConfigSource; } | 236 | get { return m_ConfigSource; } |
236 | } | 237 | } |
237 | 238 | ||
239 | private class ScriptCompileInfo | ||
240 | { | ||
241 | public List<EventParams> eventList = new List<EventParams>(); | ||
242 | } | ||
243 | |||
238 | /// <summary> | 244 | /// <summary> |
239 | /// Event fired after the script engine has finished removing a script. | 245 | /// Event fired after the script engine has finished removing a script. |
240 | /// </summary> | 246 | /// </summary> |
@@ -301,15 +307,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
301 | m_MaxScriptQueue = m_ScriptConfig.GetInt("MaxScriptEventQueue",300); | 307 | m_MaxScriptQueue = m_ScriptConfig.GetInt("MaxScriptEventQueue",300); |
302 | m_StackSize = m_ScriptConfig.GetInt("ThreadStackSize", 262144); | 308 | m_StackSize = m_ScriptConfig.GetInt("ThreadStackSize", 262144); |
303 | m_SleepTime = m_ScriptConfig.GetInt("MaintenanceInterval", 10) * 1000; | 309 | m_SleepTime = m_ScriptConfig.GetInt("MaintenanceInterval", 10) * 1000; |
304 | m_AppDomainLoading = m_ScriptConfig.GetBoolean("AppDomainLoading", true); | 310 | m_AppDomainLoading = m_ScriptConfig.GetBoolean("AppDomainLoading", false); |
305 | 311 | m_CompactMemOnLoad = m_ScriptConfig.GetBoolean("CompactMemOnLoad", false); | |
306 | m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); | 312 | m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); |
307 | m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); | 313 | m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); |
308 | m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; | 314 | m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; |
309 | m_WaitForEventCompletionOnScriptStop | 315 | m_WaitForEventCompletionOnScriptStop |
310 | = m_ScriptConfig.GetInt("WaitForEventCompletionOnScriptStop", m_WaitForEventCompletionOnScriptStop); | 316 | = m_ScriptConfig.GetInt("WaitForEventCompletionOnScriptStop", m_WaitForEventCompletionOnScriptStop); |
311 | 317 | ||
312 | m_ScriptEnginesPath = "../caches/" + m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines"); | 318 | m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines"); |
313 | 319 | ||
314 | m_Prio = ThreadPriority.BelowNormal; | 320 | m_Prio = ThreadPriority.BelowNormal; |
315 | switch (priority) | 321 | switch (priority) |
@@ -506,7 +512,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
506 | { | 512 | { |
507 | string rawItemId; | 513 | string rawItemId; |
508 | UUID itemId = UUID.Zero; | 514 | UUID itemId = UUID.Zero; |
509 | 515 | ||
510 | if (cmdparams.Length == 2) | 516 | if (cmdparams.Length == 2) |
511 | { | 517 | { |
512 | IEnumerable<IScriptInstance> scripts = m_Scripts.Values; | 518 | IEnumerable<IScriptInstance> scripts = m_Scripts.Values; |
@@ -519,17 +525,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
519 | 525 | ||
520 | return; | 526 | return; |
521 | } | 527 | } |
522 | 528 | ||
523 | for (int i = 2; i < cmdparams.Length; i++) | 529 | for (int i = 2; i < cmdparams.Length; i++) |
524 | { | 530 | { |
525 | rawItemId = cmdparams[i]; | 531 | rawItemId = cmdparams[i]; |
526 | 532 | ||
527 | if (!UUID.TryParse(rawItemId, out itemId)) | 533 | if (!UUID.TryParse(rawItemId, out itemId)) |
528 | { | 534 | { |
529 | MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId); | 535 | MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId); |
530 | continue; | 536 | continue; |
531 | } | 537 | } |
532 | 538 | ||
533 | if (itemId != UUID.Zero) | 539 | if (itemId != UUID.Zero) |
534 | { | 540 | { |
535 | IScriptInstance instance = GetInstance(itemId); | 541 | IScriptInstance instance = GetInstance(itemId); |
@@ -815,12 +821,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
815 | { | 821 | { |
816 | if (!m_Enabled) | 822 | if (!m_Enabled) |
817 | return; | 823 | return; |
818 | 824 | ||
819 | lock (m_ScriptEngines) | 825 | lock (m_ScriptEngines) |
820 | { | 826 | { |
821 | if (m_ScriptEngines.Contains(this)) | 827 | if (m_ScriptEngines.Contains(this)) |
822 | m_ScriptEngines.Remove(this); | 828 | m_ScriptEngines.Remove(this); |
823 | } | 829 | } |
830 | |||
831 | lock(m_Scripts) | ||
832 | m_ThreadPool.Shutdown(); | ||
824 | } | 833 | } |
825 | 834 | ||
826 | public object DoBackup(object o) | 835 | public object DoBackup(object o) |
@@ -977,14 +986,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
977 | SceneObjectPart part = | 986 | SceneObjectPart part = |
978 | m_Scene.GetSceneObjectPart( | 987 | m_Scene.GetSceneObjectPart( |
979 | localID); | 988 | localID); |
980 | 989 | ||
981 | TaskInventoryItem item = | 990 | TaskInventoryItem item = |
982 | part.Inventory.GetInventoryItem(itemID); | 991 | part.Inventory.GetInventoryItem(itemID); |
983 | 992 | ||
984 | ScenePresence presence = | 993 | ScenePresence presence = |
985 | m_Scene.GetScenePresence( | 994 | m_Scene.GetScenePresence( |
986 | item.OwnerID); | 995 | item.OwnerID); |
987 | 996 | ||
988 | if (presence != null) | 997 | if (presence != null) |
989 | { | 998 | { |
990 | presence.ControllingClient.SendAgentAlertMessage( | 999 | presence.ControllingClient.SendAgentAlertMessage( |
@@ -1008,7 +1017,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1008 | { | 1017 | { |
1009 | lock (m_CompileDict) | 1018 | lock (m_CompileDict) |
1010 | { | 1019 | { |
1011 | m_CompileDict[itemID] = 0; | 1020 | // m_log.DebugFormat("[XENGINE]: Set compile dict for {0}", itemID); |
1021 | m_CompileDict[itemID] = new ScriptCompileInfo(); | ||
1012 | } | 1022 | } |
1013 | 1023 | ||
1014 | DoOnRezScript(parms); | 1024 | DoOnRezScript(parms); |
@@ -1016,7 +1026,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1016 | else | 1026 | else |
1017 | { | 1027 | { |
1018 | lock (m_CompileDict) | 1028 | lock (m_CompileDict) |
1019 | m_CompileDict[itemID] = 0; | 1029 | m_CompileDict[itemID] = new ScriptCompileInfo(); |
1030 | // m_log.DebugFormat("[XENGINE]: Set compile dict for {0} delayed", itemID); | ||
1020 | 1031 | ||
1021 | // This must occur after the m_CompileDict so that an existing compile thread cannot hit the check | 1032 | // This must occur after the m_CompileDict so that an existing compile thread cannot hit the check |
1022 | // in DoOnRezScript() before m_CompileDict has been updated. | 1033 | // in DoOnRezScript() before m_CompileDict has been updated. |
@@ -1024,18 +1035,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1024 | 1035 | ||
1025 | // m_log.DebugFormat("[XEngine]: Added script {0} to compile queue", itemID); | 1036 | // m_log.DebugFormat("[XEngine]: Added script {0} to compile queue", itemID); |
1026 | 1037 | ||
1027 | if (m_CurrentCompile == null) | 1038 | // NOTE: Although we use a lockless queue, the lock here |
1039 | // is required. It ensures that there are never two | ||
1040 | // compile threads running, which, due to a race | ||
1041 | // conndition, might otherwise happen | ||
1042 | // | ||
1043 | lock (m_CompileQueue) | ||
1028 | { | 1044 | { |
1029 | // NOTE: Although we use a lockless queue, the lock here | 1045 | if (m_CurrentCompile == null) |
1030 | // is required. It ensures that there are never two | 1046 | m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); |
1031 | // compile threads running, which, due to a race | ||
1032 | // conndition, might otherwise happen | ||
1033 | // | ||
1034 | lock (m_CompileQueue) | ||
1035 | { | ||
1036 | if (m_CurrentCompile == null) | ||
1037 | m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); | ||
1038 | } | ||
1039 | } | 1047 | } |
1040 | } | 1048 | } |
1041 | } | 1049 | } |
@@ -1071,12 +1079,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1071 | "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.Name); | 1079 | "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.Name); |
1072 | } | 1080 | } |
1073 | } | 1081 | } |
1082 | catch (System.Threading.ThreadAbortException) { } | ||
1074 | catch (Exception e) | 1083 | catch (Exception e) |
1075 | { | 1084 | { |
1076 | m_log.Error( | 1085 | m_log.Error( |
1077 | string.Format( | 1086 | string.Format( |
1078 | "[XEngine]: Failure in DoOnRezScriptQueue() for item {0} in {1}. Continuing. Exception ", | 1087 | "[XEngine]: Failure in DoOnRezScriptQueue() for item {0} in {1}. Continuing. Exception ", |
1079 | o[1], m_Scene.Name), | 1088 | o[1], m_Scene.Name), |
1080 | e); | 1089 | e); |
1081 | } | 1090 | } |
1082 | } | 1091 | } |
@@ -1093,7 +1102,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1093 | } | 1102 | } |
1094 | finally | 1103 | finally |
1095 | { | 1104 | { |
1096 | // FIXME: On failure we must trigger this even if the compile queue is not actually empty so that the | 1105 | // FIXME: On failure we must trigger this even if the compile queue is not actually empty so that the |
1097 | // RegionReadyModule is not forever waiting. This event really needs a different name. | 1106 | // RegionReadyModule is not forever waiting. This event really needs a different name. |
1098 | m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount, | 1107 | m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount, |
1099 | m_ScriptErrorMessage); | 1108 | m_ScriptErrorMessage); |
@@ -1110,8 +1119,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1110 | { | 1119 | { |
1111 | m_CurrentCompile = null; | 1120 | m_CurrentCompile = null; |
1112 | 1121 | ||
1113 | // This is to avoid a situation where the m_CompileQueue while loop above could complete but | 1122 | // This is to avoid a situation where the m_CompileQueue while loop above could complete but |
1114 | // OnRezScript() place a new script on the queue and check m_CurrentCompile = null before we hit | 1123 | // OnRezScript() place a new script on the queue and check m_CurrentCompile = null before we hit |
1115 | // this section. | 1124 | // this section. |
1116 | if (m_CompileQueue.Count > 0) | 1125 | if (m_CompileQueue.Count > 0) |
1117 | m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); | 1126 | m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); |
@@ -1137,7 +1146,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1137 | { | 1146 | { |
1138 | if (!m_CompileDict.ContainsKey(itemID)) | 1147 | if (!m_CompileDict.ContainsKey(itemID)) |
1139 | return false; | 1148 | return false; |
1140 | m_CompileDict.Remove(itemID); | ||
1141 | } | 1149 | } |
1142 | 1150 | ||
1143 | // Get the asset ID of the script, so we can check if we | 1151 | // Get the asset ID of the script, so we can check if we |
@@ -1152,6 +1160,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1152 | m_log.ErrorFormat("[Script]: SceneObjectPart with localID {0} unavailable. Script NOT started.", localID); | 1160 | m_log.ErrorFormat("[Script]: SceneObjectPart with localID {0} unavailable. Script NOT started.", localID); |
1153 | m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n"; | 1161 | m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n"; |
1154 | m_ScriptFailCount++; | 1162 | m_ScriptFailCount++; |
1163 | lock (m_CompileDict) | ||
1164 | m_CompileDict.Remove(itemID); | ||
1155 | return false; | 1165 | return false; |
1156 | } | 1166 | } |
1157 | 1167 | ||
@@ -1160,6 +1170,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1160 | { | 1170 | { |
1161 | m_ScriptErrorMessage += "Can't find script inventory item.\n"; | 1171 | m_ScriptErrorMessage += "Can't find script inventory item.\n"; |
1162 | m_ScriptFailCount++; | 1172 | m_ScriptFailCount++; |
1173 | lock (m_CompileDict) | ||
1174 | m_CompileDict.Remove(itemID); | ||
1163 | return false; | 1175 | return false; |
1164 | } | 1176 | } |
1165 | 1177 | ||
@@ -1188,7 +1200,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1188 | m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assemblyPath, out linemap); | 1200 | m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assemblyPath, out linemap); |
1189 | 1201 | ||
1190 | // m_log.DebugFormat( | 1202 | // m_log.DebugFormat( |
1191 | // "[XENGINE]: Found assembly path {0} onrez {1} in {2}", | 1203 | // "[XENGINE]: Found assembly path {0} onrez {1} in {2}", |
1192 | // assemblyPath, item.ItemID, World.Name); | 1204 | // assemblyPath, item.ItemID, World.Name); |
1193 | 1205 | ||
1194 | if (!m_AddingAssemblies.ContainsKey(assemblyPath)) { | 1206 | if (!m_AddingAssemblies.ContainsKey(assemblyPath)) { |
@@ -1241,7 +1253,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1241 | catch (Exception e) | 1253 | catch (Exception e) |
1242 | { | 1254 | { |
1243 | // m_log.ErrorFormat( | 1255 | // m_log.ErrorFormat( |
1244 | // "[XEngine]: Exception when rezzing script with item ID {0}, {1}{2}", | 1256 | // "[XEngine]: Exception when rezzing script with item ID {0}, {1}{2}", |
1245 | // itemID, e.Message, e.StackTrace); | 1257 | // itemID, e.Message, e.StackTrace); |
1246 | 1258 | ||
1247 | // try | 1259 | // try |
@@ -1277,10 +1289,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1277 | // e.Message.ToString()); | 1289 | // e.Message.ToString()); |
1278 | // } | 1290 | // } |
1279 | 1291 | ||
1292 | lock (m_CompileDict) | ||
1293 | m_CompileDict.Remove(itemID); | ||
1280 | return false; | 1294 | return false; |
1281 | } | 1295 | } |
1282 | } | 1296 | } |
1283 | 1297 | ||
1298 | // optionaly do not load a assembly on top of a lot of to release memory | ||
1299 | // only if logins disable since causes a lot of rubber banding | ||
1300 | if(m_CompactMemOnLoad && !m_Scene.LoginsEnabled) | ||
1301 | GC.Collect(2); | ||
1302 | |||
1284 | ScriptInstance instance = null; | 1303 | ScriptInstance instance = null; |
1285 | lock (m_Scripts) | 1304 | lock (m_Scripts) |
1286 | { | 1305 | { |
@@ -1288,26 +1307,27 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1288 | if ((!m_Scripts.ContainsKey(itemID)) || | 1307 | if ((!m_Scripts.ContainsKey(itemID)) || |
1289 | (m_Scripts[itemID].AssetID != assetID)) | 1308 | (m_Scripts[itemID].AssetID != assetID)) |
1290 | { | 1309 | { |
1291 | UUID appDomain = assetID; | 1310 | // UUID appDomain = assetID; |
1292 | 1311 | ||
1293 | if (part.ParentGroup.IsAttachment) | 1312 | // if (part.ParentGroup.IsAttachment) |
1294 | appDomain = part.ParentGroup.RootPart.UUID; | 1313 | // appDomain = part.ParentGroup.RootPart.UUID; |
1314 | UUID appDomain = part.ParentGroup.RootPart.UUID; | ||
1295 | 1315 | ||
1296 | if (!m_AppDomains.ContainsKey(appDomain)) | 1316 | if (!m_AppDomains.ContainsKey(appDomain)) |
1297 | { | 1317 | { |
1298 | try | 1318 | try |
1299 | { | 1319 | { |
1300 | AppDomainSetup appSetup = new AppDomainSetup(); | 1320 | AppDomain sandbox; |
1301 | appSetup.PrivateBinPath = Path.Combine( | 1321 | if (m_AppDomainLoading) |
1322 | { | ||
1323 | AppDomainSetup appSetup = new AppDomainSetup(); | ||
1324 | appSetup.PrivateBinPath = Path.Combine( | ||
1302 | m_ScriptEnginesPath, | 1325 | m_ScriptEnginesPath, |
1303 | m_Scene.RegionInfo.RegionID.ToString()); | 1326 | m_Scene.RegionInfo.RegionID.ToString()); |
1304 | 1327 | ||
1305 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; | 1328 | Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; |
1306 | Evidence evidence = new Evidence(baseEvidence); | 1329 | Evidence evidence = new Evidence(baseEvidence); |
1307 | 1330 | ||
1308 | AppDomain sandbox; | ||
1309 | if (m_AppDomainLoading) | ||
1310 | { | ||
1311 | sandbox = AppDomain.CreateDomain( | 1331 | sandbox = AppDomain.CreateDomain( |
1312 | m_Scene.RegionInfo.RegionID.ToString(), | 1332 | m_Scene.RegionInfo.RegionID.ToString(), |
1313 | evidence, appSetup); | 1333 | evidence, appSetup); |
@@ -1319,7 +1339,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1319 | { | 1339 | { |
1320 | sandbox = AppDomain.CurrentDomain; | 1340 | sandbox = AppDomain.CurrentDomain; |
1321 | } | 1341 | } |
1322 | 1342 | ||
1323 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | 1343 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); |
1324 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | 1344 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); |
1325 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | 1345 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); |
@@ -1327,7 +1347,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1327 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | 1347 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); |
1328 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | 1348 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; |
1329 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | 1349 | //sandbox.SetAppDomainPolicy(sandboxPolicy); |
1330 | 1350 | ||
1331 | m_AppDomains[appDomain] = sandbox; | 1351 | m_AppDomains[appDomain] = sandbox; |
1332 | 1352 | ||
1333 | m_DomainScripts[appDomain] = new List<UUID>(); | 1353 | m_DomainScripts[appDomain] = new List<UUID>(); |
@@ -1337,10 +1357,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1337 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); | 1357 | m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); |
1338 | m_ScriptErrorMessage += "Exception creating app domain:\n"; | 1358 | m_ScriptErrorMessage += "Exception creating app domain:\n"; |
1339 | m_ScriptFailCount++; | 1359 | m_ScriptFailCount++; |
1340 | lock (m_AddingAssemblies) | 1360 | lock (m_AddingAssemblies) |
1341 | { | 1361 | { |
1342 | m_AddingAssemblies[assemblyPath]--; | 1362 | m_AddingAssemblies[assemblyPath]--; |
1343 | } | 1363 | } |
1364 | lock (m_CompileDict) | ||
1365 | m_CompileDict.Remove(itemID); | ||
1344 | return false; | 1366 | return false; |
1345 | } | 1367 | } |
1346 | } | 1368 | } |
@@ -1360,14 +1382,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1360 | { | 1382 | { |
1361 | coopSleepHandle = new XEngineEventWaitHandle(false, EventResetMode.AutoReset); | 1383 | coopSleepHandle = new XEngineEventWaitHandle(false, EventResetMode.AutoReset); |
1362 | 1384 | ||
1363 | scriptObj | 1385 | scriptObj |
1364 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( | 1386 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( |
1365 | assemblyName.FullName, | 1387 | assemblyName.FullName, |
1366 | "SecondLife.XEngineScript", | 1388 | "SecondLife.XEngineScript", |
1367 | false, | 1389 | false, |
1368 | BindingFlags.Default, | 1390 | BindingFlags.Default, |
1369 | null, | 1391 | null, |
1370 | new object[] { coopSleepHandle }, | 1392 | new object[] { coopSleepHandle }, |
1371 | null, | 1393 | null, |
1372 | null); | 1394 | null); |
1373 | 1395 | ||
@@ -1379,7 +1401,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1379 | 1401 | ||
1380 | try | 1402 | try |
1381 | { | 1403 | { |
1382 | scriptObj | 1404 | scriptObj |
1383 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( | 1405 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( |
1384 | assemblyName.FullName, | 1406 | assemblyName.FullName, |
1385 | "SecondLife.Script", | 1407 | "SecondLife.Script", |
@@ -1394,10 +1416,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1394 | { | 1416 | { |
1395 | m_log.Error( | 1417 | m_log.Error( |
1396 | string.Format( | 1418 | string.Format( |
1397 | "[XENGINE]: Could not load previous SecondLife.Script from assembly {0} in {1}. Not starting. Exception ", | 1419 | "[XENGINE]: Could not load previous SecondLife.Script from assembly {0} in {1}. Not starting. Exception ", |
1398 | assemblyName.FullName, World.Name), | 1420 | assemblyName.FullName, World.Name), |
1399 | e2); | 1421 | e2); |
1400 | 1422 | ||
1423 | lock (m_CompileDict) | ||
1424 | m_CompileDict.Remove(itemID); | ||
1401 | return false; | 1425 | return false; |
1402 | } | 1426 | } |
1403 | 1427 | ||
@@ -1408,7 +1432,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1408 | { | 1432 | { |
1409 | try | 1433 | try |
1410 | { | 1434 | { |
1411 | scriptObj | 1435 | scriptObj |
1412 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( | 1436 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( |
1413 | assemblyName.FullName, | 1437 | assemblyName.FullName, |
1414 | "SecondLife.Script", | 1438 | "SecondLife.Script", |
@@ -1428,7 +1452,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1428 | 1452 | ||
1429 | try | 1453 | try |
1430 | { | 1454 | { |
1431 | scriptObj | 1455 | scriptObj |
1432 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( | 1456 | = (IScript)m_AppDomains[appDomain].CreateInstanceAndUnwrap( |
1433 | assemblyName.FullName, | 1457 | assemblyName.FullName, |
1434 | "SecondLife.XEngineScript", | 1458 | "SecondLife.XEngineScript", |
@@ -1443,10 +1467,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1443 | { | 1467 | { |
1444 | m_log.Error( | 1468 | m_log.Error( |
1445 | string.Format( | 1469 | string.Format( |
1446 | "[XENGINE]: Could not load previous SecondLife.XEngineScript from assembly {0} in {1}. Not starting. Exception ", | 1470 | "[XENGINE]: Could not load previous SecondLife.XEngineScript from assembly {0} in {1}. Not starting. Exception ", |
1447 | assemblyName.FullName, World.Name), | 1471 | assemblyName.FullName, World.Name), |
1448 | e2); | 1472 | e2); |
1449 | 1473 | ||
1474 | lock (m_CompileDict) | ||
1475 | m_CompileDict.Remove(itemID); | ||
1450 | return false; | 1476 | return false; |
1451 | } | 1477 | } |
1452 | 1478 | ||
@@ -1454,7 +1480,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1454 | } | 1480 | } |
1455 | } | 1481 | } |
1456 | 1482 | ||
1457 | if (m_coopTermination != coopTerminationForThisScript && !HaveNotifiedLogOfScriptStopMistmatch) | 1483 | if (m_coopTermination != coopTerminationForThisScript && !HaveNotifiedLogOfScriptStopMismatch) |
1458 | { | 1484 | { |
1459 | // Notify the log that there is at least one script compile that doesn't match the | 1485 | // Notify the log that there is at least one script compile that doesn't match the |
1460 | // ScriptStopStrategy. Operator has to manually delete old DLLs - we can't do this on Windows | 1486 | // ScriptStopStrategy. Operator has to manually delete old DLLs - we can't do this on Windows |
@@ -1464,7 +1490,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1464 | + "\nContinuing with script compiled strategy but to remove this message please set [XEngine] DeleteScriptsOnStartup = true for one simulator session to remove old script DLLs (script state will not be lost).", | 1490 | + "\nContinuing with script compiled strategy but to remove this message please set [XEngine] DeleteScriptsOnStartup = true for one simulator session to remove old script DLLs (script state will not be lost).", |
1465 | World.Name, coopTerminationForThisScript ? "co-op" : "abort", m_coopTermination ? "co-op" : "abort"); | 1491 | World.Name, coopTerminationForThisScript ? "co-op" : "abort", m_coopTermination ? "co-op" : "abort"); |
1466 | 1492 | ||
1467 | HaveNotifiedLogOfScriptStopMistmatch = true; | 1493 | HaveNotifiedLogOfScriptStopMismatch = true; |
1468 | } | 1494 | } |
1469 | 1495 | ||
1470 | instance = new ScriptInstance(this, part, | 1496 | instance = new ScriptInstance(this, part, |
@@ -1472,11 +1498,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1472 | startParam, postOnRez, | 1498 | startParam, postOnRez, |
1473 | m_MaxScriptQueue); | 1499 | m_MaxScriptQueue); |
1474 | 1500 | ||
1475 | if ( | 1501 | if(!instance.Load(scriptObj, coopSleepHandle, assemblyPath, |
1476 | !instance.Load( | ||
1477 | scriptObj, coopSleepHandle, assemblyPath, | ||
1478 | Path.Combine(ScriptEnginePath, World.RegionInfo.RegionID.ToString()), stateSource, coopTerminationForThisScript)) | 1502 | Path.Combine(ScriptEnginePath, World.RegionInfo.RegionID.ToString()), stateSource, coopTerminationForThisScript)) |
1479 | return false; | 1503 | { |
1504 | lock (m_CompileDict) | ||
1505 | m_CompileDict.Remove(itemID); | ||
1506 | return false; | ||
1507 | } | ||
1480 | 1508 | ||
1481 | // if (DebugLevel >= 1) | 1509 | // if (DebugLevel >= 1) |
1482 | // m_log.DebugFormat( | 1510 | // m_log.DebugFormat( |
@@ -1506,16 +1534,26 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1506 | m_PrimObjects[localID].Add(itemID); | 1534 | m_PrimObjects[localID].Add(itemID); |
1507 | } | 1535 | } |
1508 | 1536 | ||
1509 | if (!m_Assemblies.ContainsKey(assetID)) | ||
1510 | m_Assemblies[assetID] = assemblyPath; | ||
1511 | 1537 | ||
1512 | lock (m_AddingAssemblies) | 1538 | lock (m_AddingAssemblies) |
1513 | { | 1539 | { |
1540 | if (!m_Assemblies.ContainsKey(assetID)) | ||
1541 | m_Assemblies[assetID] = assemblyPath; | ||
1542 | |||
1514 | m_AddingAssemblies[assemblyPath]--; | 1543 | m_AddingAssemblies[assemblyPath]--; |
1515 | } | 1544 | } |
1516 | 1545 | ||
1517 | if (instance != null) | 1546 | if (instance != null) |
1547 | { | ||
1518 | instance.Init(); | 1548 | instance.Init(); |
1549 | lock (m_CompileDict) | ||
1550 | { | ||
1551 | foreach (EventParams pp in m_CompileDict[itemID].eventList) | ||
1552 | instance.PostEvent(pp); | ||
1553 | } | ||
1554 | } | ||
1555 | lock (m_CompileDict) | ||
1556 | m_CompileDict.Remove(itemID); | ||
1519 | 1557 | ||
1520 | bool runIt; | 1558 | bool runIt; |
1521 | if (m_runFlags.TryGetValue(itemID, out runIt)) | 1559 | if (m_runFlags.TryGetValue(itemID, out runIt)) |
@@ -1567,7 +1605,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1567 | } | 1605 | } |
1568 | 1606 | ||
1569 | if (instance.StatePersistedHere) | 1607 | if (instance.StatePersistedHere) |
1570 | instance.RemoveState(); | 1608 | instance.RemoveState(); |
1571 | 1609 | ||
1572 | instance.DestroyScriptInstance(); | 1610 | instance.DestroyScriptInstance(); |
1573 | 1611 | ||
@@ -1619,20 +1657,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1619 | // Do not remove assembly files if another instance of the script | 1657 | // Do not remove assembly files if another instance of the script |
1620 | // is currently initialising | 1658 | // is currently initialising |
1621 | if (!m_AddingAssemblies.ContainsKey(m_Assemblies[assetID]) | 1659 | if (!m_AddingAssemblies.ContainsKey(m_Assemblies[assetID]) |
1622 | || m_AddingAssemblies[m_Assemblies[assetID]] == 0) | 1660 | || m_AddingAssemblies[m_Assemblies[assetID]] == 0) |
1623 | { | 1661 | { |
1624 | // m_log.DebugFormat("[XEngine] Removing unreferenced assembly {0}", m_Assemblies[assetID]); | 1662 | // m_log.DebugFormat("[XEngine] Removing unreferenced assembly {0}", m_Assemblies[assetID]); |
1625 | try | 1663 | try |
1626 | { | 1664 | { |
1627 | if (File.Exists(m_Assemblies[assetID])) | 1665 | if (File.Exists(m_Assemblies[assetID])) |
1628 | File.Delete(m_Assemblies[assetID]); | 1666 | File.Delete(m_Assemblies[assetID]); |
1629 | 1667 | ||
1630 | if (File.Exists(m_Assemblies[assetID]+".text")) | 1668 | if (File.Exists(m_Assemblies[assetID]+".text")) |
1631 | File.Delete(m_Assemblies[assetID]+".text"); | 1669 | File.Delete(m_Assemblies[assetID]+".text"); |
1632 | 1670 | ||
1633 | if (File.Exists(m_Assemblies[assetID]+".mdb")) | 1671 | if (File.Exists(m_Assemblies[assetID]+".mdb")) |
1634 | File.Delete(m_Assemblies[assetID]+".mdb"); | 1672 | File.Delete(m_Assemblies[assetID]+".mdb"); |
1635 | 1673 | ||
1636 | if (File.Exists(m_Assemblies[assetID]+".map")) | 1674 | if (File.Exists(m_Assemblies[assetID]+".map")) |
1637 | File.Delete(m_Assemblies[assetID]+".map"); | 1675 | File.Delete(m_Assemblies[assetID]+".map"); |
1638 | } | 1676 | } |
@@ -1689,7 +1727,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1689 | new WorkItemCallback(this.ProcessEventHandler), | 1727 | new WorkItemCallback(this.ProcessEventHandler), |
1690 | parms)); | 1728 | parms)); |
1691 | } | 1729 | } |
1692 | 1730 | ||
1693 | /// <summary> | 1731 | /// <summary> |
1694 | /// Process a previously posted script event. | 1732 | /// Process a previously posted script event. |
1695 | /// </summary> | 1733 | /// </summary> |
@@ -1700,7 +1738,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1700 | Culture.SetCurrentCulture(); | 1738 | Culture.SetCurrentCulture(); |
1701 | 1739 | ||
1702 | IScriptInstance instance = (ScriptInstance) parms; | 1740 | IScriptInstance instance = (ScriptInstance) parms; |
1703 | 1741 | ||
1704 | // m_log.DebugFormat("[XEngine]: Processing event for {0}", instance); | 1742 | // m_log.DebugFormat("[XEngine]: Processing event for {0}", instance); |
1705 | 1743 | ||
1706 | return instance.EventProcessor(); | 1744 | return instance.EventProcessor(); |
@@ -1733,15 +1771,26 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1733 | instance = m_Scripts[itemID]; | 1771 | instance = m_Scripts[itemID]; |
1734 | } | 1772 | } |
1735 | catch { /* ignore race conditions */ } | 1773 | catch { /* ignore race conditions */ } |
1736 | 1774 | ||
1737 | if (instance != null) | 1775 | if (instance != null) |
1738 | { | 1776 | { |
1739 | instance.PostEvent(p); | 1777 | instance.PostEvent(p); |
1740 | result = true; | 1778 | result = true; |
1741 | } | 1779 | } |
1780 | else | ||
1781 | { | ||
1782 | lock (m_CompileDict) | ||
1783 | { | ||
1784 | if (m_CompileDict.ContainsKey(itemID)) | ||
1785 | { | ||
1786 | m_CompileDict[itemID].eventList.Add(p); | ||
1787 | result = true; | ||
1788 | } | ||
1789 | } | ||
1790 | } | ||
1742 | } | 1791 | } |
1743 | } | 1792 | } |
1744 | 1793 | ||
1745 | return result; | 1794 | return result; |
1746 | } | 1795 | } |
1747 | 1796 | ||
@@ -1760,6 +1809,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1760 | instance.PostEvent(p); | 1809 | instance.PostEvent(p); |
1761 | return true; | 1810 | return true; |
1762 | } | 1811 | } |
1812 | lock (m_CompileDict) | ||
1813 | { | ||
1814 | if (m_CompileDict.ContainsKey(itemID)) | ||
1815 | { | ||
1816 | m_CompileDict[itemID].eventList.Add(p); | ||
1817 | return true; | ||
1818 | } | ||
1819 | } | ||
1763 | return false; | 1820 | return false; |
1764 | } | 1821 | } |
1765 | 1822 | ||
@@ -1817,7 +1874,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1817 | if (!(sender is System.AppDomain)) | 1874 | if (!(sender is System.AppDomain)) |
1818 | return null; | 1875 | return null; |
1819 | 1876 | ||
1820 | string[] pathList = new string[] {"caches", m_ScriptEnginesPath, | 1877 | string[] pathList = new string[] {"bin", m_ScriptEnginesPath, |
1821 | Path.Combine(m_ScriptEnginesPath, | 1878 | Path.Combine(m_ScriptEnginesPath, |
1822 | m_Scene.RegionInfo.RegionID.ToString())}; | 1879 | m_Scene.RegionInfo.RegionID.ToString())}; |
1823 | 1880 | ||
@@ -1851,15 +1908,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1851 | return instance; | 1908 | return instance; |
1852 | } | 1909 | } |
1853 | 1910 | ||
1854 | public void SetScriptState(UUID itemID, bool running) | 1911 | public void SetScriptState(UUID itemID, bool running, bool self) |
1855 | { | 1912 | { |
1856 | IScriptInstance instance = GetInstance(itemID); | 1913 | IScriptInstance instance = GetInstance(itemID); |
1857 | if (instance != null) | 1914 | if (instance != null) |
1858 | { | 1915 | { |
1859 | if (running) | 1916 | if (running) |
1860 | instance.Start(); | 1917 | instance.Start(); |
1861 | else | 1918 | else |
1862 | instance.Stop(100); | 1919 | { |
1920 | if(self) | ||
1921 | { | ||
1922 | instance.Running = false; | ||
1923 | throw new EventAbortException(); | ||
1924 | } | ||
1925 | else | ||
1926 | instance.Stop(100); | ||
1927 | } | ||
1863 | } | 1928 | } |
1864 | } | 1929 | } |
1865 | 1930 | ||
@@ -2033,6 +2098,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
2033 | string xml = instance.GetXMLState(); | 2098 | string xml = instance.GetXMLState(); |
2034 | 2099 | ||
2035 | XmlDocument sdoc = new XmlDocument(); | 2100 | XmlDocument sdoc = new XmlDocument(); |
2101 | sdoc.XmlResolver=null; | ||
2036 | bool loadedState = true; | 2102 | bool loadedState = true; |
2037 | try | 2103 | try |
2038 | { | 2104 | { |
@@ -2084,10 +2150,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
2084 | string fn = Path.GetFileName(assemName); | 2150 | string fn = Path.GetFileName(assemName); |
2085 | 2151 | ||
2086 | string assem = String.Empty; | 2152 | string assem = String.Empty; |
2153 | string assemNameText = assemName + ".text"; | ||
2087 | 2154 | ||
2088 | if (File.Exists(assemName + ".text")) | 2155 | if (File.Exists(assemNameText)) |
2089 | { | 2156 | { |
2090 | FileInfo tfi = new FileInfo(assemName + ".text"); | 2157 | FileInfo tfi = new FileInfo(assemNameText); |
2091 | 2158 | ||
2092 | if (tfi != null) | 2159 | if (tfi != null) |
2093 | { | 2160 | { |
@@ -2095,7 +2162,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
2095 | 2162 | ||
2096 | try | 2163 | try |
2097 | { | 2164 | { |
2098 | using (FileStream tfs = File.Open(assemName + ".text", | 2165 | using (FileStream tfs = File.Open(assemNameText, |
2099 | FileMode.Open, FileAccess.Read)) | 2166 | FileMode.Open, FileAccess.Read)) |
2100 | { | 2167 | { |
2101 | tfs.Read(tdata, 0, tdata.Length); | 2168 | tfs.Read(tdata, 0, tdata.Length); |
@@ -2187,6 +2254,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
2187 | return false; | 2254 | return false; |
2188 | 2255 | ||
2189 | XmlDocument doc = new XmlDocument(); | 2256 | XmlDocument doc = new XmlDocument(); |
2257 | doc.XmlResolver=null; | ||
2190 | 2258 | ||
2191 | try | 2259 | try |
2192 | { | 2260 | { |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs b/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs index 9d9dee1..ede8ef3 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs | |||
@@ -60,7 +60,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
60 | public bool Wait(int t) | 60 | public bool Wait(int t) |
61 | { | 61 | { |
62 | // We use the integer version of WaitAll because the current version of SmartThreadPool has a bug with the | 62 | // We use the integer version of WaitAll because the current version of SmartThreadPool has a bug with the |
63 | // TimeSpan version. The number of milliseconds in TimeSpan is an int64 so when STP casts it down to an | 63 | // TimeSpan version. The number of milliseconds in TimeSpan is an int64 so when STP casts it down to an |
64 | // int (32-bit) we can end up with bad values. This occurs on Windows though curiously not on Mono 2.10.8 | 64 | // int (32-bit) we can end up with bad values. This occurs on Windows though curiously not on Mono 2.10.8 |
65 | // (or very likely other versions of Mono at least up until 3.0.3). | 65 | // (or very likely other versions of Mono at least up until 3.0.3). |
66 | return SmartThreadPool.WaitAll(new IWorkItemResult[] {wr}, t, false); | 66 | return SmartThreadPool.WaitAll(new IWorkItemResult[] {wr}, t, false); |