diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XMREngine/XMREngine.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XMREngine/XMREngine.cs | 1064 |
1 files changed, 509 insertions, 555 deletions
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMREngine.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMREngine.cs index 6b0410a..aa8573c 100644 --- a/OpenSim/Region/ScriptEngine/XMREngine/XMREngine.cs +++ b/OpenSim/Region/ScriptEngine/XMREngine/XMREngine.cs | |||
@@ -25,6 +25,10 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | // based on XMREngine from Mike Rieker (Dreamnation) and Melanie Thielker | ||
29 | // but with several changes to be more cross platform. | ||
30 | |||
31 | |||
28 | using log4net; | 32 | using log4net; |
29 | using Mono.Addins; | 33 | using Mono.Addins; |
30 | using Nini.Config; | 34 | using Nini.Config; |
@@ -37,11 +41,11 @@ using OpenSim.Region.Framework.Scenes; | |||
37 | using OpenSim.Region.ScriptEngine.Interfaces; | 41 | using OpenSim.Region.ScriptEngine.Interfaces; |
38 | using OpenSim.Region.ScriptEngine.Shared; | 42 | using OpenSim.Region.ScriptEngine.Shared; |
39 | using OpenSim.Region.ScriptEngine.Shared.Api; | 43 | using OpenSim.Region.ScriptEngine.Shared.Api; |
40 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
41 | using OpenMetaverse; | 44 | using OpenMetaverse; |
42 | using System; | 45 | using System; |
43 | using System.Collections; | 46 | using System.Collections; |
44 | using System.Collections.Generic; | 47 | using System.Collections.Generic; |
48 | using System.Diagnostics; | ||
45 | using System.IO; | 49 | using System.IO; |
46 | using System.Reflection; | 50 | using System.Reflection; |
47 | using System.Reflection.Emit; | 51 | using System.Reflection.Emit; |
@@ -97,7 +101,6 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
97 | private int m_HeapSize; | 101 | private int m_HeapSize; |
98 | private XMRScriptThread[] m_ScriptThreads; | 102 | private XMRScriptThread[] m_ScriptThreads; |
99 | private Thread m_SleepThread = null; | 103 | private Thread m_SleepThread = null; |
100 | // private Thread m_SliceThread = null; | ||
101 | private bool m_Exiting = false; | 104 | private bool m_Exiting = false; |
102 | 105 | ||
103 | private int m_MaintenanceInterval = 10; | 106 | private int m_MaintenanceInterval = 10; |
@@ -107,15 +110,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
107 | private object m_FrameUpdateLock = new object (); | 110 | private object m_FrameUpdateLock = new object (); |
108 | private event ThreadStart m_FrameUpdateList = null; | 111 | private event ThreadStart m_FrameUpdateList = null; |
109 | 112 | ||
110 | /* | 113 | // Various instance lists: |
111 | * Various instance lists: | 114 | // m_InstancesDict = all known instances |
112 | * m_InstancesDict = all known instances | 115 | // find an instance given its itemID |
113 | * find an instance given its itemID | 116 | // m_StartQueue = instances that have just had event queued to them |
114 | * m_StartQueue = instances that have just had event queued to them | 117 | // m_YieldQueue = instances that are ready to run right now |
115 | * m_YieldQueue = instances that are ready to run right now | 118 | // m_SleepQueue = instances that have m_SleepUntil valid |
116 | * m_SleepQueue = instances that have m_SleepUntil valid | 119 | // sorted by ascending m_SleepUntil |
117 | * sorted by ascending m_SleepUntil | 120 | |
118 | */ | ||
119 | private Dictionary<UUID, XMRInstance> m_InstancesDict = | 121 | private Dictionary<UUID, XMRInstance> m_InstancesDict = |
120 | new Dictionary<UUID, XMRInstance>(); | 122 | new Dictionary<UUID, XMRInstance>(); |
121 | public Queue<ThreadStart> m_ThunkQueue = new Queue<ThreadStart> (); | 123 | public Queue<ThreadStart> m_ThunkQueue = new Queue<ThreadStart> (); |
@@ -126,19 +128,6 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
126 | 128 | ||
127 | public XMREngine() | 129 | public XMREngine() |
128 | { | 130 | { |
129 | string envar; | ||
130 | |||
131 | envar = Environment.GetEnvironmentVariable ("XMREngineTraceCalls"); | ||
132 | m_TraceCalls = (envar != null) && ((envar[0] & 1) != 0); | ||
133 | m_log.Info ("[XMREngine]: m_TraceCalls=" + m_TraceCalls); | ||
134 | |||
135 | envar = Environment.GetEnvironmentVariable ("XMREngineVerbose"); | ||
136 | m_Verbose = (envar != null) && ((envar[0] & 1) != 0); | ||
137 | m_log.Info ("[XMREngine]: m_Verbose=" + m_Verbose); | ||
138 | |||
139 | envar = Environment.GetEnvironmentVariable ("XMREngineScriptDebug"); | ||
140 | m_ScriptDebug = (envar != null) && ((envar[0] & 1) != 0); | ||
141 | m_log.Info ("[XMREngine]: m_ScriptDebug=" + m_ScriptDebug); | ||
142 | } | 131 | } |
143 | 132 | ||
144 | public string Name | 133 | public string Name |
@@ -190,97 +179,66 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
190 | 179 | ||
191 | m_Enabled = false; | 180 | m_Enabled = false; |
192 | m_Config = config.Configs["XMREngine"]; | 181 | m_Config = config.Configs["XMREngine"]; |
193 | if (m_Config == null) { | 182 | if (m_Config == null) |
183 | { | ||
194 | m_log.Info("[XMREngine]: no config, assuming disabled"); | 184 | m_log.Info("[XMREngine]: no config, assuming disabled"); |
195 | return; | 185 | return; |
196 | } | 186 | } |
187 | |||
197 | m_Enabled = m_Config.GetBoolean("Enabled", false); | 188 | m_Enabled = m_Config.GetBoolean("Enabled", false); |
198 | m_log.InfoFormat("[XMREngine]: config enabled={0}", m_Enabled); | 189 | m_log.InfoFormat("[XMREngine]: config enabled={0}", m_Enabled); |
199 | if (!m_Enabled) { | 190 | if (!m_Enabled) |
200 | return; | 191 | return; |
201 | } | ||
202 | |||
203 | string uThreadModel = "sys"; // will work anywhere | ||
204 | uThreadModel = m_Config.GetString ("UThreadModel", uThreadModel); | ||
205 | 192 | ||
206 | Type uThreadType = null; | 193 | Type uThreadType = null; |
207 | switch (uThreadModel.ToLower ()) { | 194 | uThreadType = typeof (ScriptUThread_Nul); |
208 | |||
209 | // mono continuations - memcpy()s the stack | ||
210 | case "con": { | ||
211 | uThreadType = typeof (ScriptUThread_Con); | ||
212 | break; | ||
213 | } | ||
214 | |||
215 | // patched mono microthreads - switches stack pointer | ||
216 | case "mmr": { | ||
217 | Exception e = ScriptUThread_MMR.LoadMono (); | ||
218 | if (e != null) { | ||
219 | m_log.Error ("[XMREngine]: mmr thread model not available\n", e); | ||
220 | m_Enabled = false; | ||
221 | return; | ||
222 | } | ||
223 | uThreadType = typeof (ScriptUThread_MMR); | ||
224 | break; | ||
225 | } | ||
226 | |||
227 | // system threads - works on mono and windows | ||
228 | case "sys": { | ||
229 | uThreadType = typeof (ScriptUThread_Sys); | ||
230 | break; | ||
231 | } | ||
232 | |||
233 | // who knows what | ||
234 | default: { | ||
235 | m_log.Error ("[XMREngine]: unknown thread model " + uThreadModel); | ||
236 | m_Enabled = false; | ||
237 | return; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | uThreadCtor = uThreadType.GetConstructor (new Type[] { typeof (XMRInstance) }); | 195 | uThreadCtor = uThreadType.GetConstructor (new Type[] { typeof (XMRInstance) }); |
242 | m_log.Info ("[XMREngine]: using thread model " + uThreadModel); | ||
243 | 196 | ||
244 | m_UseSourceHashCode = m_Config.GetBoolean ("UseSourceHashCode", false); | 197 | m_UseSourceHashCode = m_Config.GetBoolean("UseSourceHashCode", false); |
245 | numThreadScriptWorkers = m_Config.GetInt ("NumThreadScriptWorkers", 1); | 198 | numThreadScriptWorkers = m_Config.GetInt("NumThreadScriptWorkers", 3); |
246 | m_ScriptThreads = new XMRScriptThread[numThreadScriptWorkers]; | 199 | m_ScriptThreads = new XMRScriptThread[numThreadScriptWorkers]; |
247 | 200 | ||
248 | for (int i = 0; i < numThreadScriptWorkers; i ++) { | 201 | m_TraceCalls = m_Config.GetBoolean("TraceCalls", false); |
249 | m_ScriptThreads[i] = new XMRScriptThread(this); | 202 | m_Verbose = m_Config.GetBoolean("Verbose", false); |
250 | } | 203 | m_ScriptDebug = m_Config.GetBoolean("ScriptDebug", false); |
251 | 204 | ||
252 | m_SleepThread = StartMyThread (RunSleepThread, "xmrengine sleep", ThreadPriority.Normal); | 205 | // Verify that our ScriptEventCode's match OpenSim's scriptEvent's. |
253 | // m_SliceThread = StartMyThread (RunSliceThread, "xmrengine slice", ThreadPriority.Normal); | ||
254 | |||
255 | /* | ||
256 | * Verify that our ScriptEventCode's match OpenSim's scriptEvent's. | ||
257 | */ | ||
258 | bool err = false; | 206 | bool err = false; |
259 | for (int i = 0; i < 32; i ++) { | 207 | for (int i = 0; i < 32; i ++) |
208 | { | ||
260 | string mycode = "undefined"; | 209 | string mycode = "undefined"; |
261 | string oscode = "undefined"; | 210 | string oscode = "undefined"; |
262 | try { | 211 | try |
212 | { | ||
263 | mycode = ((ScriptEventCode)i).ToString(); | 213 | mycode = ((ScriptEventCode)i).ToString(); |
264 | Convert.ToInt32(mycode); | 214 | Convert.ToInt32(mycode); |
265 | mycode = "undefined"; | 215 | mycode = "undefined"; |
266 | } catch { | ||
267 | } | 216 | } |
268 | try { | 217 | catch { } |
218 | try | ||
219 | { | ||
269 | oscode = ((OpenSim.Region.Framework.Scenes.scriptEvents)(1 << i)).ToString(); | 220 | oscode = ((OpenSim.Region.Framework.Scenes.scriptEvents)(1 << i)).ToString(); |
270 | Convert.ToInt32(oscode); | 221 | Convert.ToInt32(oscode); |
271 | oscode = "undefined"; | 222 | oscode = "undefined"; |
272 | } catch { | ||
273 | } | 223 | } |
274 | if (mycode != oscode) { | 224 | catch { } |
225 | if (mycode != oscode) | ||
226 | { | ||
275 | m_log.ErrorFormat("[XMREngine]: {0} mycode={1}, oscode={2}", i, mycode, oscode); | 227 | m_log.ErrorFormat("[XMREngine]: {0} mycode={1}, oscode={2}", i, mycode, oscode); |
276 | err = true; | 228 | err = true; |
277 | } | 229 | } |
278 | } | 230 | } |
279 | if (err) { | 231 | if (err) |
232 | { | ||
280 | m_Enabled = false; | 233 | m_Enabled = false; |
281 | return; | 234 | return; |
282 | } | 235 | } |
283 | 236 | ||
237 | for (int i = 0; i < numThreadScriptWorkers; i ++) | ||
238 | m_ScriptThreads[i] = new XMRScriptThread(this, i); | ||
239 | |||
240 | m_SleepThread = StartMyThread(RunSleepThread, "xmrengine sleep", ThreadPriority.Normal); | ||
241 | |||
284 | m_StackSize = m_Config.GetInt("ScriptStackSize", 2048) << 10; | 242 | m_StackSize = m_Config.GetInt("ScriptStackSize", 2048) << 10; |
285 | m_HeapSize = m_Config.GetInt("ScriptHeapSize", 1024) << 10; | 243 | m_HeapSize = m_Config.GetInt("ScriptHeapSize", 1024) << 10; |
286 | 244 | ||
@@ -337,12 +295,11 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
337 | 295 | ||
338 | private void OneTimeLateInitialization () | 296 | private void OneTimeLateInitialization () |
339 | { | 297 | { |
340 | /* | 298 | // Build list of defined APIs and their 'this' types and define a field in XMRInstanceSuperType. |
341 | * Build list of defined APIs and their 'this' types and define a field in XMRInstanceSuperType. | ||
342 | */ | ||
343 | ApiManager am = new ApiManager (); | 299 | ApiManager am = new ApiManager (); |
344 | Dictionary<string,Type> apiCtxTypes = new Dictionary<string,Type> (); | 300 | Dictionary<string,Type> apiCtxTypes = new Dictionary<string,Type> (); |
345 | foreach (string api in am.GetApis ()) { | 301 | foreach (string api in am.GetApis ()) |
302 | { | ||
346 | m_log.Debug ("[XMREngine]: adding api " + api); | 303 | m_log.Debug ("[XMREngine]: adding api " + api); |
347 | IScriptApi scriptApi = am.CreateApi (api); | 304 | IScriptApi scriptApi = am.CreateApi (api); |
348 | Type apiCtxType = scriptApi.GetType (); | 305 | Type apiCtxType = scriptApi.GetType (); |
@@ -352,25 +309,36 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
352 | 309 | ||
353 | if (ScriptCodeGen.xmrInstSuperType == null) // Only create type once! | 310 | if (ScriptCodeGen.xmrInstSuperType == null) // Only create type once! |
354 | { | 311 | { |
355 | /* | 312 | // Start creating type XMRInstanceSuperType that contains a field |
356 | * Start creating type XMRInstanceSuperType that contains a field | 313 | // m_ApiManager_<APINAME> that points to the per-instance context |
357 | * m_ApiManager_<APINAME> that points to the per-instance context | 314 | // struct for that API, ie, the 'this' value passed to all methods |
358 | * struct for that API, ie, the 'this' value passed to all methods | 315 | // in that API. It is in essence: |
359 | * in that API. It is in essence: | 316 | |
360 | * | 317 | // public class XMRInstanceSuperType : XMRInstance { |
361 | * public class XMRInstanceSuperType : XMRInstance { | 318 | // public XMRLSL_Api m_ApiManager_LSL; // 'this' value for all ll...() functions |
362 | * public XMRLSL_Api m_ApiManager_LSL; // 'this' value for all ll...() functions | 319 | // public MOD_Api m_ApiManager_MOD; // 'this' value for all mod...() functions |
363 | * public MOD_Api m_ApiManager_MOD; // 'this' value for all mod...() functions | 320 | // public OSSL_Api m_ApiManager_OSSL; // 'this' value for all os...() functions |
364 | * public OSSL_Api m_ApiManager_OSSL; // 'this' value for all os...() functions | 321 | // .... |
365 | * .... | 322 | // } |
366 | * } | 323 | |
367 | */ | ||
368 | AssemblyName assemblyName = new AssemblyName (); | 324 | AssemblyName assemblyName = new AssemblyName (); |
369 | assemblyName.Name = "XMRInstanceSuperAssembly"; | 325 | assemblyName.Name = "XMRInstanceSuperAssembly"; |
370 | AssemblyBuilder assemblyBuilder = Thread.GetDomain ().DefineDynamicAssembly (assemblyName, AssemblyBuilderAccess.Run); | 326 | AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); |
371 | ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule ("XMRInstanceSuperModule"); | 327 | #if DEBUG |
372 | TypeBuilder typeBuilder = moduleBuilder.DefineType ("XMRInstanceSuperType", TypeAttributes.Public | TypeAttributes.Class); | 328 | Type daType = typeof(DebuggableAttribute); |
373 | typeBuilder.SetParent (typeof (XMRInstance)); | 329 | ConstructorInfo daCtor = daType.GetConstructor(new Type[] { typeof(DebuggableAttribute.DebuggingModes) }); |
330 | |||
331 | CustomAttributeBuilder daBuilder = new CustomAttributeBuilder(daCtor, new object[] { | ||
332 | DebuggableAttribute.DebuggingModes.DisableOptimizations | | ||
333 | DebuggableAttribute.DebuggingModes.EnableEditAndContinue | | ||
334 | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | | ||
335 | DebuggableAttribute.DebuggingModes.Default }); | ||
336 | |||
337 | assemblyBuilder.SetCustomAttribute(daBuilder); | ||
338 | #endif | ||
339 | ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("XMRInstanceSuperModule"); | ||
340 | TypeBuilder typeBuilder = moduleBuilder.DefineType("XMRInstanceSuperType", TypeAttributes.Public | TypeAttributes.Class); | ||
341 | typeBuilder.SetParent(typeof (XMRInstance)); | ||
374 | 342 | ||
375 | foreach (string apiname in apiCtxTypes.Keys) | 343 | foreach (string apiname in apiCtxTypes.Keys) |
376 | { | 344 | { |
@@ -378,23 +346,20 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
378 | typeBuilder.DefineField (fieldName, apiCtxTypes[apiname], FieldAttributes.Public); | 346 | typeBuilder.DefineField (fieldName, apiCtxTypes[apiname], FieldAttributes.Public); |
379 | } | 347 | } |
380 | 348 | ||
381 | /* | 349 | // Finalize definition of XMRInstanceSuperType. |
382 | * Finalize definition of XMRInstanceSuperType. | 350 | // Give the compiler a short name to reference it by, |
383 | * Give the compiler a short name to reference it by, | 351 | // otherwise it will try to use the AssemblyQualifiedName |
384 | * otherwise it will try to use the AssemblyQualifiedName | 352 | // and fail miserably. |
385 | * and fail miserably. | ||
386 | */ | ||
387 | ScriptCodeGen.xmrInstSuperType = typeBuilder.CreateType (); | 353 | ScriptCodeGen.xmrInstSuperType = typeBuilder.CreateType (); |
388 | ScriptObjWriter.DefineInternalType ("xmrsuper", ScriptCodeGen.xmrInstSuperType); | 354 | ScriptObjWriter.DefineInternalType ("xmrsuper", ScriptCodeGen.xmrInstSuperType); |
389 | } | 355 | } |
390 | 356 | ||
391 | /* | 357 | // Tell the compiler about all the constants and methods for each API. |
392 | * Tell the compiler about all the constants and methods for each API. | 358 | // We also tell the compiler how to get the per-instance context for each API |
393 | * We also tell the compiler how to get the per-instance context for each API | 359 | // by reading the corresponding m_ApiManager_<APINAME> field of XMRInstanceSuperType. |
394 | * by reading the corresponding m_ApiManager_<APINAME> field of XMRInstanceSuperType. | ||
395 | */ | ||
396 | foreach (KeyValuePair<string,Type> kvp in apiCtxTypes) { | ||
397 | 360 | ||
361 | foreach (KeyValuePair<string,Type> kvp in apiCtxTypes) | ||
362 | { | ||
398 | // get API name and the corresponding per-instance context type | 363 | // get API name and the corresponding per-instance context type |
399 | string api = kvp.Key; | 364 | string api = kvp.Key; |
400 | Type apiCtxType = kvp.Value; | 365 | Type apiCtxType = kvp.Value; |
@@ -413,41 +378,47 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
413 | TokenDeclInline.AddInterfaceMethods (null, apiCtxType.GetMethods (), fieldInfo); | 378 | TokenDeclInline.AddInterfaceMethods (null, apiCtxType.GetMethods (), fieldInfo); |
414 | } | 379 | } |
415 | 380 | ||
416 | /* | 381 | // Add sim-specific APIs to the compiler. |
417 | * Add sim-specific APIs to the compiler. | ||
418 | */ | ||
419 | IScriptModuleComms comms = m_Scene.RequestModuleInterface<IScriptModuleComms> (); | ||
420 | if (comms != null) { | ||
421 | 382 | ||
422 | /* | 383 | IScriptModuleComms comms = m_Scene.RequestModuleInterface<IScriptModuleComms> (); |
423 | * Add methods to list of built-in functions. | 384 | if (comms != null) |
424 | */ | 385 | { |
386 | // Add methods to list of built-in functions. | ||
425 | Delegate[] methods = comms.GetScriptInvocationList (); | 387 | Delegate[] methods = comms.GetScriptInvocationList (); |
426 | foreach (Delegate m in methods) { | 388 | foreach (Delegate m in methods) |
389 | { | ||
427 | MethodInfo mi = m.Method; | 390 | MethodInfo mi = m.Method; |
428 | try { | 391 | try |
392 | { | ||
429 | CommsCallCodeGen cccg = new CommsCallCodeGen (mi, comms, m_XMRInstanceApiCtxFieldInfos["MOD"]); | 393 | CommsCallCodeGen cccg = new CommsCallCodeGen (mi, comms, m_XMRInstanceApiCtxFieldInfos["MOD"]); |
430 | Verbose ("[XMREngine]: added comms function " + cccg.fullName); | 394 | Verbose ("[XMREngine]: added comms function " + cccg.fullName); |
431 | } catch (Exception e) { | 395 | } |
396 | catch (Exception e) | ||
397 | { | ||
432 | m_log.Error ("[XMREngine]: failed to add comms function " + mi.Name); | 398 | m_log.Error ("[XMREngine]: failed to add comms function " + mi.Name); |
433 | m_log.Error ("[XMREngine]: - " + e.ToString ()); | 399 | m_log.Error ("[XMREngine]: - " + e.ToString ()); |
434 | } | 400 | } |
435 | } | 401 | } |
436 | 402 | ||
437 | /* | 403 | // Add constants to list of built-in constants. |
438 | * Add constants to list of built-in constants. | 404 | |
439 | */ | ||
440 | Dictionary<string,object> consts = comms.GetConstants (); | 405 | Dictionary<string,object> consts = comms.GetConstants (); |
441 | foreach (KeyValuePair<string,object> kvp in consts) { | 406 | foreach (KeyValuePair<string,object> kvp in consts) |
442 | try { | 407 | { |
408 | try | ||
409 | { | ||
443 | ScriptConst sc = ScriptConst.AddConstant (kvp.Key, kvp.Value); | 410 | ScriptConst sc = ScriptConst.AddConstant (kvp.Key, kvp.Value); |
444 | Verbose ("[XMREngine]: added comms constant " + sc.name); | 411 | Verbose ("[XMREngine]: added comms constant " + sc.name); |
445 | } catch (Exception e) { | 412 | } |
413 | catch (Exception e) | ||
414 | { | ||
446 | m_log.Error ("[XMREngine]: failed to add comms constant " + kvp.Key); | 415 | m_log.Error ("[XMREngine]: failed to add comms constant " + kvp.Key); |
447 | m_log.Error ("[XMREngine]: - " + e.Message); | 416 | m_log.Error ("[XMREngine]: - " + e.Message); |
448 | } | 417 | } |
449 | } | 418 | } |
450 | } else { | 419 | } |
420 | else | ||
421 | { | ||
451 | Verbose ("[XMREngine]: comms not enabled"); | 422 | Verbose ("[XMREngine]: comms not enabled"); |
452 | } | 423 | } |
453 | } | 424 | } |
@@ -461,7 +432,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
461 | * do some sick type conversions (with corresponding mallocs) so we can't | 432 | * do some sick type conversions (with corresponding mallocs) so we can't |
462 | * call the methods directly. | 433 | * call the methods directly. |
463 | */ | 434 | */ |
464 | private class CommsCallCodeGen : TokenDeclInline { | 435 | private class CommsCallCodeGen : TokenDeclInline |
436 | { | ||
465 | private static Type[] modInvokerArgTypes = new Type[] { typeof (string), typeof (object[]) }; | 437 | private static Type[] modInvokerArgTypes = new Type[] { typeof (string), typeof (object[]) }; |
466 | public static FieldInfo xmrInstModApiCtxField; | 438 | public static FieldInfo xmrInstModApiCtxField; |
467 | 439 | ||
@@ -492,8 +464,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
492 | { | 464 | { |
493 | methName = mi.Name; | 465 | methName = mi.Name; |
494 | string modInvokerName = comms.LookupModInvocation (methName); | 466 | string modInvokerName = comms.LookupModInvocation (methName); |
495 | if (modInvokerName == null) throw new Exception ("cannot find comms method " + methName); | 467 | if (modInvokerName == null) |
496 | modInvokerMeth = typeof (MOD_Api).GetMethod (modInvokerName, modInvokerArgTypes); | 468 | throw new Exception("cannot find comms method " + methName); |
469 | modInvokerMeth = typeof(MOD_Api).GetMethod(modInvokerName, modInvokerArgTypes); | ||
497 | xmrInstModApiCtxField = apictxfi; | 470 | xmrInstModApiCtxField = apictxfi; |
498 | } | 471 | } |
499 | 472 | ||
@@ -504,7 +477,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
504 | sb.Append (mi.Name); | 477 | sb.Append (mi.Name); |
505 | sb.Append ('('); | 478 | sb.Append ('('); |
506 | ParameterInfo[] mps = mi.GetParameters (); | 479 | ParameterInfo[] mps = mi.GetParameters (); |
507 | for (int i = 2; i < mps.Length; i ++) { | 480 | for (int i = 2; i < mps.Length; i ++) |
481 | { | ||
508 | ParameterInfo pi = mps[i]; | 482 | ParameterInfo pi = mps[i]; |
509 | if (i > 2) sb.Append (','); | 483 | if (i > 2) sb.Append (','); |
510 | sb.Append (ParamType (pi.ParameterType)); | 484 | sb.Append (ParamType (pi.ParameterType)); |
@@ -551,36 +525,31 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
551 | */ | 525 | */ |
552 | public override void CodeGen (ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args) | 526 | public override void CodeGen (ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args) |
553 | { | 527 | { |
554 | /* | 528 | // Set up 'this' pointer for modInvoker?() = value from ApiManager.CreateApi("MOD"). |
555 | * Set up 'this' pointer for modInvoker?() = value from ApiManager.CreateApi("MOD"). | ||
556 | */ | ||
557 | scg.PushXMRInst (); | 529 | scg.PushXMRInst (); |
558 | scg.ilGen.Emit (errorAt, OpCodes.Castclass, xmrInstModApiCtxField.DeclaringType); | 530 | scg.ilGen.Emit (errorAt, OpCodes.Castclass, xmrInstModApiCtxField.DeclaringType); |
559 | scg.ilGen.Emit (errorAt, OpCodes.Ldfld, xmrInstModApiCtxField); | 531 | scg.ilGen.Emit (errorAt, OpCodes.Ldfld, xmrInstModApiCtxField); |
560 | 532 | ||
561 | /* | 533 | // Set up 'fname' argument to modInvoker?() = name of the function to be called. |
562 | * Set up 'fname' argument to modInvoker?() = name of the function to be called. | ||
563 | */ | ||
564 | scg.ilGen.Emit (errorAt, OpCodes.Ldstr, methName); | 534 | scg.ilGen.Emit (errorAt, OpCodes.Ldstr, methName); |
565 | 535 | ||
566 | /* | 536 | // Set up 'parms' argument to modInvoker?() = object[] of the script-visible parameters, |
567 | * Set up 'parms' argument to modInvoker?() = object[] of the script-visible parameters, | 537 | // in their LSL-wrapped form. Of course, the modInvoker?() method will malloc yet another |
568 | * in their LSL-wrapped form. Of course, the modInvoker?() method will malloc yet another | 538 | // object[] and type-convert these parameters one-by-one with another round of unwrapping |
569 | * object[] and type-convert these parameters one-by-one with another round of unwrapping | 539 | // and wrapping. |
570 | * and wrapping. | 540 | // Types allowed in this object[]: |
571 | * Types allowed in this object[]: | 541 | // LSL_Float, LSL_Integer, LSL_Key, LSL_List, LSL_Rotation, LSL_String, LSL_Vector |
572 | * LSL_Float, LSL_Integer, LSL_Key, LSL_List, LSL_Rotation, LSL_String, LSL_Vector | 542 | |
573 | */ | ||
574 | int nargs = args.Length; | 543 | int nargs = args.Length; |
575 | scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4, nargs); | 544 | scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4, nargs); |
576 | scg.ilGen.Emit (errorAt, OpCodes.Newarr, typeof (object)); | 545 | scg.ilGen.Emit (errorAt, OpCodes.Newarr, typeof (object)); |
577 | 546 | ||
578 | for (int i = 0; i < nargs; i ++) { | 547 | for (int i = 0; i < nargs; i ++) |
548 | { | ||
579 | scg.ilGen.Emit (errorAt, OpCodes.Dup); | 549 | scg.ilGen.Emit (errorAt, OpCodes.Dup); |
580 | scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4, i); | 550 | scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4, i); |
581 | 551 | ||
582 | // get location and type of argument | 552 | // get location and type of argument |
583 | |||
584 | CompValu arg = args[i]; | 553 | CompValu arg = args[i]; |
585 | TokenType argtype = arg.type; | 554 | TokenType argtype = arg.type; |
586 | 555 | ||
@@ -593,68 +562,84 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
593 | // then convert to object by boxing if necessary | 562 | // then convert to object by boxing if necessary |
594 | 563 | ||
595 | Type boxit = null; | 564 | Type boxit = null; |
596 | if (argtype is TokenTypeLSLFloat) { | 565 | if (argtype is TokenTypeLSLFloat) |
566 | { | ||
597 | args[i].PushVal (scg, errorAt); | 567 | args[i].PushVal (scg, errorAt); |
598 | boxit = typeof (LSL_Float); | 568 | boxit = typeof (LSL_Float); |
599 | } else if (argtype is TokenTypeLSLInt) { | 569 | } |
570 | else if (argtype is TokenTypeLSLInt) | ||
571 | { | ||
600 | args[i].PushVal (scg, errorAt); | 572 | args[i].PushVal (scg, errorAt); |
601 | boxit = typeof (LSL_Integer); | 573 | boxit = typeof (LSL_Integer); |
602 | } else if (argtype is TokenTypeLSLKey) { | 574 | } |
575 | else if (argtype is TokenTypeLSLKey) | ||
576 | { | ||
603 | args[i].PushVal (scg, errorAt); | 577 | args[i].PushVal (scg, errorAt); |
604 | boxit = typeof (LSL_Key); | 578 | boxit = typeof (LSL_Key); |
605 | } else if (argtype is TokenTypeList) { | 579 | } |
580 | else if (argtype is TokenTypeList) | ||
581 | { | ||
606 | args[i].PushVal (scg, errorAt); | 582 | args[i].PushVal (scg, errorAt); |
607 | boxit = typeof (LSL_List); | 583 | boxit = typeof (LSL_List); |
608 | } else if (argtype is TokenTypeRot) { | 584 | } |
585 | else if (argtype is TokenTypeRot) | ||
586 | { | ||
609 | args[i].PushVal (scg, errorAt); | 587 | args[i].PushVal (scg, errorAt); |
610 | boxit = typeof (LSL_Rotation); | 588 | boxit = typeof (LSL_Rotation); |
611 | } else if (argtype is TokenTypeLSLString) { | 589 | } |
590 | else if (argtype is TokenTypeLSLString) | ||
591 | { | ||
612 | args[i].PushVal (scg, errorAt); | 592 | args[i].PushVal (scg, errorAt); |
613 | boxit = typeof (LSL_String); | 593 | boxit = typeof (LSL_String); |
614 | } else if (argtype is TokenTypeVec) { | 594 | } |
595 | else if (argtype is TokenTypeVec) | ||
596 | { | ||
615 | args[i].PushVal (scg, errorAt); | 597 | args[i].PushVal (scg, errorAt); |
616 | boxit = typeof (LSL_Vector); | 598 | boxit = typeof (LSL_Vector); |
617 | } else if (argtype is TokenTypeFloat) { | 599 | } |
600 | else if (argtype is TokenTypeFloat) | ||
601 | { | ||
618 | args[i].PushVal (scg, errorAt, new TokenTypeLSLFloat (argtype)); | 602 | args[i].PushVal (scg, errorAt, new TokenTypeLSLFloat (argtype)); |
619 | boxit = typeof (LSL_Float); | 603 | boxit = typeof (LSL_Float); |
620 | } else if (argtype is TokenTypeInt) { | 604 | } |
605 | else if (argtype is TokenTypeInt) | ||
606 | { | ||
621 | args[i].PushVal (scg, errorAt, new TokenTypeLSLInt (argtype)); | 607 | args[i].PushVal (scg, errorAt, new TokenTypeLSLInt (argtype)); |
622 | boxit = typeof (LSL_Integer); | 608 | boxit = typeof (LSL_Integer); |
623 | } else if (argtype is TokenTypeKey) { | 609 | } |
610 | else if (argtype is TokenTypeKey) | ||
611 | { | ||
624 | args[i].PushVal (scg, errorAt, new TokenTypeLSLKey (argtype)); | 612 | args[i].PushVal (scg, errorAt, new TokenTypeLSLKey (argtype)); |
625 | boxit = typeof (LSL_Key); | 613 | boxit = typeof (LSL_Key); |
626 | } else if (argtype is TokenTypeStr) { | 614 | } |
615 | else if (argtype is TokenTypeStr) | ||
616 | { | ||
627 | args[i].PushVal (scg, errorAt, new TokenTypeLSLString (argtype)); | 617 | args[i].PushVal (scg, errorAt, new TokenTypeLSLString (argtype)); |
628 | boxit = typeof (LSL_String); | 618 | boxit = typeof (LSL_String); |
629 | } else { | ||
630 | throw new Exception ("unsupported arg type " + argtype.GetType ().Name); | ||
631 | } | 619 | } |
632 | if (boxit.IsValueType) { | 620 | else |
621 | throw new Exception ("unsupported arg type " + argtype.GetType ().Name); | ||
622 | |||
623 | if (boxit.IsValueType) | ||
633 | scg.ilGen.Emit (errorAt, OpCodes.Box, boxit); | 624 | scg.ilGen.Emit (errorAt, OpCodes.Box, boxit); |
634 | } | ||
635 | 625 | ||
636 | // pop the object into the object[] | 626 | // pop the object into the object[] |
637 | |||
638 | scg.ilGen.Emit (errorAt, OpCodes.Stelem, typeof (object)); | 627 | scg.ilGen.Emit (errorAt, OpCodes.Stelem, typeof (object)); |
639 | } | 628 | } |
640 | 629 | ||
641 | /* | 630 | // Call the modInvoker?() method. |
642 | * Call the modInvoker?() method. | 631 | // It leaves an LSL-wrapped type on the stack. |
643 | * It leaves an LSL-wrapped type on the stack. | 632 | if (modInvokerMeth.IsVirtual) |
644 | */ | ||
645 | if (modInvokerMeth.IsVirtual) { | ||
646 | scg.ilGen.Emit (errorAt, OpCodes.Callvirt, modInvokerMeth); | 633 | scg.ilGen.Emit (errorAt, OpCodes.Callvirt, modInvokerMeth); |
647 | } else { | 634 | else |
648 | scg.ilGen.Emit (errorAt, OpCodes.Call, modInvokerMeth); | 635 | scg.ilGen.Emit (errorAt, OpCodes.Call, modInvokerMeth); |
649 | } | ||
650 | 636 | ||
651 | /* | 637 | // The 3rd arg to Pop() is the type on the stack, |
652 | * The 3rd arg to Pop() is the type on the stack, | 638 | // ie, what modInvoker?() actually returns. |
653 | * ie, what modInvoker?() actually returns. | 639 | // The Pop() method will wrap/unwrap as needed. |
654 | * The Pop() method will wrap/unwrap as needed. | ||
655 | */ | ||
656 | Type retSysType = modInvokerMeth.ReturnType; | 640 | Type retSysType = modInvokerMeth.ReturnType; |
657 | if (retSysType == null) retSysType = typeof (void); | 641 | if (retSysType == null) |
642 | retSysType = typeof (void); | ||
658 | TokenType retTokType = TokenType.FromSysType (errorAt, retSysType); | 643 | TokenType retTokType = TokenType.FromSysType (errorAt, retSysType); |
659 | result.Pop (scg, errorAt, retTokType); | 644 | result.Pop (scg, errorAt, retTokType); |
660 | } | 645 | } |
@@ -671,17 +656,23 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
671 | 656 | ||
672 | TraceCalls("[XMREngine]: XMREngine.RemoveRegion({0})", scene.RegionInfo.RegionName); | 657 | TraceCalls("[XMREngine]: XMREngine.RemoveRegion({0})", scene.RegionInfo.RegionName); |
673 | 658 | ||
674 | /* | 659 | // Write script states out to .state files so it will be |
675 | * Write script states out to .state files so it will be | 660 | // available when the region is restarted. |
676 | * available when the region is restarted. | ||
677 | */ | ||
678 | DoMaintenance(null, null); | 661 | DoMaintenance(null, null); |
679 | 662 | ||
680 | /* | 663 | // Stop executing script threads and wait for final |
681 | * Stop executing script threads and wait for final | 664 | // one to finish (ie, script gets to CheckRun() call). |
682 | * one to finish (ie, script gets to CheckRun() call). | ||
683 | */ | ||
684 | m_Exiting = true; | 665 | m_Exiting = true; |
666 | |||
667 | m_Scene.EventManager.OnFrame -= OnFrame; | ||
668 | m_Scene.EventManager.OnRezScript -= OnRezScript; | ||
669 | m_Scene.EventManager.OnRemoveScript -= OnRemoveScript; | ||
670 | m_Scene.EventManager.OnScriptReset -= OnScriptReset; | ||
671 | m_Scene.EventManager.OnStartScript -= OnStartScript; | ||
672 | m_Scene.EventManager.OnStopScript -= OnStopScript; | ||
673 | m_Scene.EventManager.OnGetScriptRunning -= OnGetScriptRunning; | ||
674 | m_Scene.EventManager.OnShutdown -= OnShutdown; | ||
675 | |||
685 | for (int i = 0; i < numThreadScriptWorkers; i ++) | 676 | for (int i = 0; i < numThreadScriptWorkers; i ++) |
686 | { | 677 | { |
687 | XMRScriptThread scriptThread = m_ScriptThreads[i]; | 678 | XMRScriptThread scriptThread = m_ScriptThreads[i]; |
@@ -702,21 +693,6 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
702 | m_SleepThread.Abort(); | 693 | m_SleepThread.Abort(); |
703 | m_SleepThread = null; | 694 | m_SleepThread = null; |
704 | } | 695 | } |
705 | /* | ||
706 | if (m_SliceThread != null) | ||
707 | { | ||
708 | m_SliceThread.Join(); | ||
709 | m_SliceThread = null; | ||
710 | } | ||
711 | */ | ||
712 | m_Scene.EventManager.OnFrame -= OnFrame; | ||
713 | m_Scene.EventManager.OnRezScript -= OnRezScript; | ||
714 | m_Scene.EventManager.OnRemoveScript -= OnRemoveScript; | ||
715 | m_Scene.EventManager.OnScriptReset -= OnScriptReset; | ||
716 | m_Scene.EventManager.OnStartScript -= OnStartScript; | ||
717 | m_Scene.EventManager.OnStopScript -= OnStopScript; | ||
718 | m_Scene.EventManager.OnGetScriptRunning -= OnGetScriptRunning; | ||
719 | m_Scene.EventManager.OnShutdown -= OnShutdown; | ||
720 | 696 | ||
721 | m_Enabled = false; | 697 | m_Enabled = false; |
722 | m_Scene = null; | 698 | m_Scene = null; |
@@ -758,46 +734,51 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
758 | 734 | ||
759 | private void RunTest (string module, string[] args) | 735 | private void RunTest (string module, string[] args) |
760 | { | 736 | { |
761 | if (args.Length < 2) { | 737 | if (args.Length < 2) |
738 | { | ||
762 | m_log.Info ("[XMREngine]: missing command, try 'xmr help'"); | 739 | m_log.Info ("[XMREngine]: missing command, try 'xmr help'"); |
763 | return; | 740 | return; |
764 | } | 741 | } |
765 | 742 | ||
766 | switch (args[1]) { | 743 | switch (args[1]) |
767 | case "cvv": { | 744 | { |
768 | switch (args.Length) { | 745 | case "cvv": |
769 | case 2: { | 746 | switch (args.Length) |
747 | { | ||
748 | case 2: | ||
770 | m_log.InfoFormat ("[XMREngine]: compiled version value = {0}", | 749 | m_log.InfoFormat ("[XMREngine]: compiled version value = {0}", |
771 | ScriptCodeGen.COMPILED_VERSION_VALUE); | 750 | ScriptCodeGen.COMPILED_VERSION_VALUE); |
772 | break; | 751 | break; |
773 | } | 752 | |
774 | case 3: { | 753 | case 3: |
775 | try { | 754 | try |
755 | { | ||
776 | ScriptCodeGen.COMPILED_VERSION_VALUE = Convert.ToInt32 (args[2]); | 756 | ScriptCodeGen.COMPILED_VERSION_VALUE = Convert.ToInt32 (args[2]); |
777 | } catch { | 757 | } |
758 | catch | ||
759 | { | ||
778 | m_log.Error ("[XMREngine]: bad/missing version number"); | 760 | m_log.Error ("[XMREngine]: bad/missing version number"); |
779 | } | 761 | } |
780 | break; | 762 | break; |
781 | } | 763 | |
782 | default: { | 764 | default: |
783 | m_log.Error ("[XMREngine]: xmr cvv [<new_compiled_version_value>]"); | 765 | m_log.Error ("[XMREngine]: xmr cvv [<new_compiled_version_value>]"); |
784 | break; | 766 | break; |
785 | } | ||
786 | } | 767 | } |
787 | break; | 768 | break; |
788 | } | 769 | |
789 | case "echo": { | 770 | case "echo": |
790 | for (int i = 0; i < args.Length; i ++) { | 771 | for (int i = 0; i < args.Length; i ++) |
791 | m_log.Info ("[XMREngine]: echo[" + i + "]=<" + args[i] + ">"); | 772 | m_log.Info ("[XMREngine]: echo[" + i + "]=<" + args[i] + ">"); |
792 | } | 773 | |
793 | break; | 774 | break; |
794 | } | 775 | |
795 | case "gc": { | 776 | case "gc": |
796 | GC.Collect(); | 777 | GC.Collect(); |
797 | break; | 778 | break; |
798 | } | 779 | |
799 | case "help": | 780 | case "help": |
800 | case "?": { | 781 | case "?": |
801 | m_log.Info ("[XMREngine]: xmr cvv [<newvalue>] - show/set compiled version value"); | 782 | m_log.Info ("[XMREngine]: xmr cvv [<newvalue>] - show/set compiled version value"); |
802 | m_log.Info ("[XMREngine]: xmr gc"); | 783 | m_log.Info ("[XMREngine]: xmr gc"); |
803 | m_log.Info ("[XMREngine]: xmr ls [-help ...]"); | 784 | m_log.Info ("[XMREngine]: xmr ls [-help ...]"); |
@@ -809,75 +790,74 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
809 | m_log.Info ("[XMREngine]: xmr tracecalls [yes | no]"); | 790 | m_log.Info ("[XMREngine]: xmr tracecalls [yes | no]"); |
810 | m_log.Info ("[XMREngine]: xmr verbose [yes | no]"); | 791 | m_log.Info ("[XMREngine]: xmr verbose [yes | no]"); |
811 | break; | 792 | break; |
812 | } | 793 | |
813 | case "ls": { | 794 | case "ls": |
814 | XmrTestLs (args, 2); | 795 | XmrTestLs (args, 2); |
815 | break; | 796 | break; |
816 | } | 797 | |
817 | case "mvv": { | 798 | case "mvv": |
818 | switch (args.Length) { | 799 | switch (args.Length) |
819 | case 2: { | 800 | { |
801 | case 2: | ||
820 | m_log.InfoFormat ("[XMREngine]: migration version value = {0}", | 802 | m_log.InfoFormat ("[XMREngine]: migration version value = {0}", |
821 | XMRInstance.migrationVersion); | 803 | XMRInstance.migrationVersion); |
822 | break; | 804 | break; |
823 | } | 805 | |
824 | case 3: { | 806 | case 3: |
825 | try { | 807 | try |
808 | { | ||
826 | int mvv = Convert.ToInt32 (args[2]); | 809 | int mvv = Convert.ToInt32 (args[2]); |
827 | if ((mvv < 0) || (mvv > 255)) throw new Exception ("out of range"); | 810 | if ((mvv < 0) || (mvv > 255)) throw new Exception ("out of range"); |
828 | XMRInstance.migrationVersion = (byte) mvv; | 811 | XMRInstance.migrationVersion = (byte) mvv; |
829 | } catch (Exception e) { | 812 | } |
813 | catch (Exception e) | ||
814 | { | ||
830 | m_log.Error ("[XMREngine]: bad/missing version number (" + e.Message + ")"); | 815 | m_log.Error ("[XMREngine]: bad/missing version number (" + e.Message + ")"); |
831 | } | 816 | } |
832 | break; | 817 | break; |
833 | } | 818 | |
834 | default: { | 819 | default: |
835 | m_log.Error ("[XMREngine]: xmr mvv [<new_migration_version_value>]"); | 820 | m_log.Error ("[XMREngine]: xmr mvv [<new_migration_version_value>]"); |
836 | break; | 821 | break; |
837 | } | ||
838 | } | 822 | } |
839 | break; | 823 | break; |
840 | } | 824 | |
841 | case "pev": { | 825 | case "pev": |
842 | XmrTestPev (args, 2); | 826 | XmrTestPev (args, 2); |
843 | break; | 827 | break; |
844 | } | 828 | |
845 | case "reset": { | 829 | case "reset": |
846 | XmrTestReset (args, 2); | 830 | XmrTestReset (args, 2); |
847 | break; | 831 | break; |
848 | } | 832 | |
849 | case "resume": { | 833 | case "resume": |
850 | m_log.Info ("[XMREngine]: resuming scripts"); | 834 | m_log.Info ("[XMREngine]: resuming scripts"); |
851 | for (int i = 0; i < numThreadScriptWorkers; i ++) { | 835 | for (int i = 0; i < numThreadScriptWorkers; i ++) |
852 | m_ScriptThreads[i].ResumeThread(); | 836 | m_ScriptThreads[i].ResumeThread(); |
853 | } | 837 | |
854 | break; | 838 | break; |
855 | } | 839 | |
856 | case "suspend": { | 840 | case "suspend": |
857 | m_log.Info ("[XMREngine]: suspending scripts"); | 841 | m_log.Info ("[XMREngine]: suspending scripts"); |
858 | for (int i = 0; i < numThreadScriptWorkers; i ++) { | 842 | for (int i = 0; i < numThreadScriptWorkers; i ++) |
859 | m_ScriptThreads[i].SuspendThread(); | 843 | m_ScriptThreads[i].SuspendThread(); |
860 | } | ||
861 | break; | 844 | break; |
862 | } | 845 | |
863 | case "tracecalls": { | 846 | case "tracecalls": |
864 | if (args.Length > 2) { | 847 | if (args.Length > 2) |
865 | m_TraceCalls = (args[2][0] & 1) != 0; | 848 | m_TraceCalls = (args[2][0] & 1) != 0; |
866 | } | ||
867 | m_log.Info ("[XMREngine]: tracecalls " + (m_TraceCalls ? "yes" : "no")); | 849 | m_log.Info ("[XMREngine]: tracecalls " + (m_TraceCalls ? "yes" : "no")); |
868 | break; | 850 | break; |
869 | } | 851 | |
870 | case "verbose": { | 852 | case "verbose": |
871 | if (args.Length > 2) { | 853 | if (args.Length > 2) |
872 | m_Verbose = (args[2][0] & 1) != 0; | 854 | m_Verbose = (args[2][0] & 1) != 0; |
873 | } | ||
874 | m_log.Info ("[XMREngine]: verbose " + (m_Verbose ? "yes" : "no")); | 855 | m_log.Info ("[XMREngine]: verbose " + (m_Verbose ? "yes" : "no")); |
875 | break; | 856 | break; |
876 | } | 857 | |
877 | default: { | 858 | default: |
878 | m_log.Error ("[XMREngine]: unknown command " + args[1] + ", try 'xmr help'"); | 859 | m_log.Error ("[XMREngine]: unknown command " + args[1] + ", try 'xmr help'"); |
879 | break; | 860 | break; |
880 | } | ||
881 | } | 861 | } |
882 | } | 862 | } |
883 | 863 | ||
@@ -935,23 +915,21 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
935 | 915 | ||
936 | TraceCalls("[XMREngine]: XMREngine.PostObjectEvent({0},{1})", localID.ToString(), parms.EventName); | 916 | TraceCalls("[XMREngine]: XMREngine.PostObjectEvent({0},{1})", localID.ToString(), parms.EventName); |
937 | 917 | ||
938 | /* | 918 | // In SecondLife, attach events go to all scripts of all prims |
939 | * In SecondLife, attach events go to all scripts of all prims | 919 | // in a linked object. So here we duplicate that functionality, |
940 | * in a linked object. So here we duplicate that functionality, | 920 | // as all we ever get is a single attach event for the whole |
941 | * as all we ever get is a single attach event for the whole | 921 | // object. |
942 | * object. | 922 | if (parms.EventName == "attach") |
943 | */ | 923 | { |
944 | if (parms.EventName == "attach") { | ||
945 | bool posted = false; | 924 | bool posted = false; |
946 | foreach (SceneObjectPart primpart in part.ParentGroup.Parts) { | 925 | foreach (SceneObjectPart primpart in part.ParentGroup.Parts) |
926 | { | ||
947 | posted |= PostPrimEvent (primpart, parms); | 927 | posted |= PostPrimEvent (primpart, parms); |
948 | } | 928 | } |
949 | return posted; | 929 | return posted; |
950 | } | 930 | } |
951 | 931 | ||
952 | /* | 932 | // Other events go to just the scripts in that prim. |
953 | * Other events go to just the scripts in that prim. | ||
954 | */ | ||
955 | return PostPrimEvent (part, parms); | 933 | return PostPrimEvent (part, parms); |
956 | } | 934 | } |
957 | 935 | ||
@@ -959,34 +937,33 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
959 | { | 937 | { |
960 | UUID partUUID = part.UUID; | 938 | UUID partUUID = part.UUID; |
961 | 939 | ||
962 | /* | 940 | // Get list of script instances running in the object. |
963 | * Get list of script instances running in the object. | ||
964 | */ | ||
965 | XMRInstance[] objInstArray; | 941 | XMRInstance[] objInstArray; |
966 | lock (m_InstancesDict) { | 942 | lock (m_InstancesDict) |
967 | if (!m_ObjectInstArray.TryGetValue (partUUID, out objInstArray)) { | 943 | { |
944 | if (!m_ObjectInstArray.TryGetValue (partUUID, out objInstArray)) | ||
968 | return false; | 945 | return false; |
969 | } | 946 | |
970 | if (objInstArray == null) { | 947 | if (objInstArray == null) |
948 | { | ||
971 | objInstArray = RebuildObjectInstArray (partUUID); | 949 | objInstArray = RebuildObjectInstArray (partUUID); |
972 | m_ObjectInstArray[partUUID] = objInstArray; | 950 | m_ObjectInstArray[partUUID] = objInstArray; |
973 | } | 951 | } |
974 | } | 952 | } |
975 | 953 | ||
976 | /* | 954 | // Post event to all script instances in the object. |
977 | * Post event to all script instances in the object. | ||
978 | */ | ||
979 | if (objInstArray.Length <= 0) return false; | 955 | if (objInstArray.Length <= 0) return false; |
980 | foreach (XMRInstance inst in objInstArray) { | 956 | foreach (XMRInstance inst in objInstArray) |
981 | inst.PostEvent (parms); | 957 | inst.PostEvent (parms); |
982 | } | 958 | |
983 | return true; | 959 | return true; |
984 | } | 960 | } |
985 | 961 | ||
986 | public DetectParams GetDetectParams(UUID itemID, int number) | 962 | public DetectParams GetDetectParams(UUID itemID, int number) |
987 | { | 963 | { |
988 | XMRInstance instance = GetInstance (itemID); | 964 | XMRInstance instance = GetInstance (itemID); |
989 | if (instance == null) return null; | 965 | if (instance == null) |
966 | return null; | ||
990 | return instance.GetDetectParams(number); | 967 | return instance.GetDetectParams(number); |
991 | } | 968 | } |
992 | 969 | ||
@@ -997,7 +974,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
997 | public int GetStartParameter(UUID itemID) | 974 | public int GetStartParameter(UUID itemID) |
998 | { | 975 | { |
999 | XMRInstance instance = GetInstance (itemID); | 976 | XMRInstance instance = GetInstance (itemID); |
1000 | if (instance == null) return 0; | 977 | if (instance == null) |
978 | return 0; | ||
1001 | return instance.StartParam; | 979 | return instance.StartParam; |
1002 | } | 980 | } |
1003 | 981 | ||
@@ -1010,9 +988,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1010 | public void SetScriptState(UUID itemID, bool state) | 988 | public void SetScriptState(UUID itemID, bool state) |
1011 | { | 989 | { |
1012 | XMRInstance instance = GetInstance (itemID); | 990 | XMRInstance instance = GetInstance (itemID); |
1013 | if (instance != null) { | 991 | if (instance != null) |
1014 | instance.Running = state; | 992 | instance.Running = state; |
1015 | } | ||
1016 | } | 993 | } |
1017 | 994 | ||
1018 | // Control display of the "running" checkbox | 995 | // Control display of the "running" checkbox |
@@ -1020,7 +997,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1020 | public bool GetScriptState(UUID itemID) | 997 | public bool GetScriptState(UUID itemID) |
1021 | { | 998 | { |
1022 | XMRInstance instance = GetInstance (itemID); | 999 | XMRInstance instance = GetInstance (itemID); |
1023 | if (instance == null) return false; | 1000 | if (instance == null) |
1001 | return false; | ||
1024 | return instance.Running; | 1002 | return instance.Running; |
1025 | } | 1003 | } |
1026 | 1004 | ||
@@ -1032,15 +1010,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1032 | public void ApiResetScript(UUID itemID) | 1010 | public void ApiResetScript(UUID itemID) |
1033 | { | 1011 | { |
1034 | XMRInstance instance = GetInstance (itemID); | 1012 | XMRInstance instance = GetInstance (itemID); |
1035 | if (instance != null) { | 1013 | if (instance != null) |
1036 | instance.ApiReset(); | 1014 | instance.ApiReset(); |
1037 | } | ||
1038 | } | 1015 | } |
1039 | 1016 | ||
1040 | public void ResetScript(UUID itemID) | 1017 | public void ResetScript(UUID itemID) |
1041 | { | 1018 | { |
1042 | XMRInstance instance = GetInstance (itemID); | 1019 | XMRInstance instance = GetInstance (itemID); |
1043 | if (instance != null) { | 1020 | if (instance != null) |
1021 | { | ||
1044 | IUrlModule urlModule = m_Scene.RequestModuleInterface<IUrlModule>(); | 1022 | IUrlModule urlModule = m_Scene.RequestModuleInterface<IUrlModule>(); |
1045 | if (urlModule != null) | 1023 | if (urlModule != null) |
1046 | urlModule.ScriptRemoved(itemID); | 1024 | urlModule.ScriptRemoved(itemID); |
@@ -1067,7 +1045,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1067 | public IScriptApi GetApi(UUID itemID, string name) | 1045 | public IScriptApi GetApi(UUID itemID, string name) |
1068 | { | 1046 | { |
1069 | FieldInfo fi; | 1047 | FieldInfo fi; |
1070 | if (!m_XMRInstanceApiCtxFieldInfos.TryGetValue (name, out fi)) return null; | 1048 | if (!m_XMRInstanceApiCtxFieldInfos.TryGetValue (name, out fi)) |
1049 | return null; | ||
1071 | XMRInstance inst = GetInstance (itemID); | 1050 | XMRInstance inst = GetInstance (itemID); |
1072 | if (inst == null) return null; | 1051 | if (inst == null) return null; |
1073 | return (IScriptApi)fi.GetValue (inst); | 1052 | return (IScriptApi)fi.GetValue (inst); |
@@ -1081,11 +1060,13 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1081 | public string GetXMLState(UUID itemID) | 1060 | public string GetXMLState(UUID itemID) |
1082 | { | 1061 | { |
1083 | XMRInstance instance = GetInstance (itemID); | 1062 | XMRInstance instance = GetInstance (itemID); |
1084 | if (instance == null) return String.Empty; | 1063 | if (instance == null) |
1064 | return String.Empty; | ||
1085 | 1065 | ||
1086 | TraceCalls("[XMREngine]: XMREngine.GetXMLState({0})", itemID.ToString()); | 1066 | TraceCalls("[XMREngine]: XMREngine.GetXMLState({0})", itemID.ToString()); |
1087 | 1067 | ||
1088 | if (!instance.m_HasRun) return String.Empty; | 1068 | if (!instance.m_HasRun) |
1069 | return String.Empty; | ||
1089 | 1070 | ||
1090 | XmlDocument doc = new XmlDocument(); | 1071 | XmlDocument doc = new XmlDocument(); |
1091 | 1072 | ||
@@ -1108,10 +1089,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1108 | assetA.Value = assetID; | 1089 | assetA.Value = assetID; |
1109 | stateN.Attributes.Append(assetA); | 1090 | stateN.Attributes.Append(assetA); |
1110 | 1091 | ||
1111 | /* | 1092 | // Get <ScriptState>...</ScriptState> item that hold's script's state. |
1112 | * Get <ScriptState>...</ScriptState> item that hold's script's state. | 1093 | // This suspends the script if necessary then takes a snapshot. |
1113 | * This suspends the script if necessary then takes a snapshot. | ||
1114 | */ | ||
1115 | XmlElement scriptStateN = instance.GetExecutionState(doc); | 1094 | XmlElement scriptStateN = instance.GetExecutionState(doc); |
1116 | stateN.AppendChild(scriptStateN); | 1095 | stateN.AppendChild(scriptStateN); |
1117 | 1096 | ||
@@ -1147,13 +1126,12 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1147 | 1126 | ||
1148 | // <ScriptState>...</ScriptState> contains contents of .state file. | 1127 | // <ScriptState>...</ScriptState> contains contents of .state file. |
1149 | XmlElement scriptStateN = (XmlElement)stateN.SelectSingleNode("ScriptState"); | 1128 | XmlElement scriptStateN = (XmlElement)stateN.SelectSingleNode("ScriptState"); |
1150 | if (scriptStateN == null) { | 1129 | if (scriptStateN == null) |
1151 | return false; | 1130 | return false; |
1152 | } | 1131 | |
1153 | string sen = stateN.GetAttribute("Engine"); | 1132 | string sen = stateN.GetAttribute("Engine"); |
1154 | if ((sen == null) || (sen != ScriptEngineName)) { | 1133 | if ((sen == null) || (sen != ScriptEngineName)) |
1155 | return false; | 1134 | return false; |
1156 | } | ||
1157 | 1135 | ||
1158 | XmlAttribute assetA = doc.CreateAttribute("", "Asset", ""); | 1136 | XmlAttribute assetA = doc.CreateAttribute("", "Asset", ""); |
1159 | assetA.Value = stateN.GetAttribute("Asset"); | 1137 | assetA.Value = stateN.GetAttribute("Asset"); |
@@ -1198,9 +1176,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1198 | public void SleepScript(UUID itemID, int delay) | 1176 | public void SleepScript(UUID itemID, int delay) |
1199 | { | 1177 | { |
1200 | XMRInstance instance = GetInstance (itemID); | 1178 | XMRInstance instance = GetInstance (itemID); |
1201 | if (instance != null) { | 1179 | if (instance != null) |
1202 | instance.Sleep (delay); | 1180 | instance.Sleep (delay); |
1203 | } | ||
1204 | } | 1181 | } |
1205 | 1182 | ||
1206 | // Get a script instance loaded, compiling it if necessary | 1183 | // Get a script instance loaded, compiling it if necessary |
@@ -1219,21 +1196,18 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1219 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | 1196 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); |
1220 | TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID); | 1197 | TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID); |
1221 | 1198 | ||
1222 | if (!m_LateInit) { | 1199 | if (!m_LateInit) |
1200 | { | ||
1223 | m_LateInit = true; | 1201 | m_LateInit = true; |
1224 | OneTimeLateInitialization (); | 1202 | OneTimeLateInitialization (); |
1225 | } | 1203 | } |
1226 | 1204 | ||
1227 | TraceCalls("[XMREngine]: OnRezScript(...,{0},...)", itemID.ToString()); | 1205 | TraceCalls("[XMREngine]: OnRezScript(...,{0},...)", itemID.ToString()); |
1228 | 1206 | ||
1229 | /* | 1207 | // Assume script uses the default engine, whatever that is. |
1230 | * Assume script uses the default engine, whatever that is. | ||
1231 | */ | ||
1232 | string engineName = defEngine; | 1208 | string engineName = defEngine; |
1233 | 1209 | ||
1234 | /* | 1210 | // Very first line might contain "//" scriptengine ":". |
1235 | * Very first line might contain "//" scriptengine ":". | ||
1236 | */ | ||
1237 | string firstline = ""; | 1211 | string firstline = ""; |
1238 | if (script.StartsWith("//")) { | 1212 | if (script.StartsWith("//")) { |
1239 | int lineEnd = script.IndexOf('\n'); | 1213 | int lineEnd = script.IndexOf('\n'); |
@@ -1245,39 +1219,32 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1245 | } | 1219 | } |
1246 | } | 1220 | } |
1247 | 1221 | ||
1248 | /* | 1222 | // Make sure the default or requested engine is us. |
1249 | * Make sure the default or requested engine is us. | ||
1250 | */ | ||
1251 | if (engineName != ScriptEngineName) { | 1223 | if (engineName != ScriptEngineName) { |
1252 | 1224 | ||
1253 | /* | 1225 | // Not us, if requested engine exists, silently ignore script and let |
1254 | * Not us, if requested engine exists, silently ignore script and let | 1226 | // requested engine handle it. |
1255 | * requested engine handle it. | ||
1256 | */ | ||
1257 | IScriptModule[] engines = m_Scene.RequestModuleInterfaces<IScriptModule> (); | 1227 | IScriptModule[] engines = m_Scene.RequestModuleInterfaces<IScriptModule> (); |
1258 | foreach (IScriptModule eng in engines) { | 1228 | foreach (IScriptModule eng in engines) |
1259 | if (eng.ScriptEngineName == engineName) { | 1229 | { |
1230 | if (eng.ScriptEngineName == engineName) | ||
1260 | return; | 1231 | return; |
1261 | } | ||
1262 | } | 1232 | } |
1263 | 1233 | ||
1264 | /* | 1234 | // Requested engine not defined, warn on console. |
1265 | * Requested engine not defined, warn on console. | 1235 | // Then we try to handle it if we're the default engine, else we ignore it. |
1266 | * Then we try to handle it if we're the default engine, else we ignore it. | ||
1267 | */ | ||
1268 | m_log.Warn ("[XMREngine]: " + itemID.ToString() + " requests undefined/disabled engine " + engineName); | 1236 | m_log.Warn ("[XMREngine]: " + itemID.ToString() + " requests undefined/disabled engine " + engineName); |
1269 | m_log.Info ("[XMREngine]: - " + part.GetWorldPosition ()); | 1237 | m_log.Info ("[XMREngine]: - " + part.GetWorldPosition ()); |
1270 | m_log.Info ("[XMREngine]: first line: " + firstline); | 1238 | m_log.Info ("[XMREngine]: first line: " + firstline); |
1271 | if (defEngine != ScriptEngineName) { | 1239 | if (defEngine != ScriptEngineName) |
1240 | { | ||
1272 | m_log.Info ("[XMREngine]: leaving it to the default script engine (" + defEngine + ") to process it"); | 1241 | m_log.Info ("[XMREngine]: leaving it to the default script engine (" + defEngine + ") to process it"); |
1273 | return; | 1242 | return; |
1274 | } | 1243 | } |
1275 | m_log.Info ("[XMREngine]: will attempt to processing it anyway as default script engine"); | 1244 | m_log.Info ("[XMREngine]: will attempt to processing it anyway as default script engine"); |
1276 | } | 1245 | } |
1277 | 1246 | ||
1278 | /* | 1247 | // Put on object/instance lists. |
1279 | * Put on object/instance lists. | ||
1280 | */ | ||
1281 | XMRInstance instance = (XMRInstance)Activator.CreateInstance (ScriptCodeGen.xmrInstSuperType); | 1248 | XMRInstance instance = (XMRInstance)Activator.CreateInstance (ScriptCodeGen.xmrInstSuperType); |
1282 | instance.m_LocalID = localID; | 1249 | instance.m_LocalID = localID; |
1283 | instance.m_ItemID = itemID; | 1250 | instance.m_ItemID = itemID; |
@@ -1291,7 +1258,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1291 | instance.m_DescName = part.Name + ":" + item.Name; | 1258 | instance.m_DescName = part.Name + ":" + item.Name; |
1292 | instance.m_IState = XMRInstState.CONSTRUCT; | 1259 | instance.m_IState = XMRInstState.CONSTRUCT; |
1293 | 1260 | ||
1294 | lock (m_InstancesDict) { | 1261 | lock (m_InstancesDict) |
1262 | { | ||
1295 | m_LockedDict = "RegisterInstance"; | 1263 | m_LockedDict = "RegisterInstance"; |
1296 | 1264 | ||
1297 | // Insert on internal list of all scripts being handled by this engine instance. | 1265 | // Insert on internal list of all scripts being handled by this engine instance. |
@@ -1300,11 +1268,13 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1300 | // Insert on internal list of all scripts being handled by this engine instance | 1268 | // Insert on internal list of all scripts being handled by this engine instance |
1301 | // that are part of the object. | 1269 | // that are part of the object. |
1302 | List<UUID> itemIDList; | 1270 | List<UUID> itemIDList; |
1303 | if (!m_ObjectItemList.TryGetValue(instance.m_PartUUID, out itemIDList)) { | 1271 | if (!m_ObjectItemList.TryGetValue(instance.m_PartUUID, out itemIDList)) |
1272 | { | ||
1304 | itemIDList = new List<UUID>(); | 1273 | itemIDList = new List<UUID>(); |
1305 | m_ObjectItemList[instance.m_PartUUID] = itemIDList; | 1274 | m_ObjectItemList[instance.m_PartUUID] = itemIDList; |
1306 | } | 1275 | } |
1307 | if (!itemIDList.Contains(instance.m_ItemID)) { | 1276 | if (!itemIDList.Contains(instance.m_ItemID)) |
1277 | { | ||
1308 | itemIDList.Add(instance.m_ItemID); | 1278 | itemIDList.Add(instance.m_ItemID); |
1309 | m_ObjectInstArray[instance.m_PartUUID] = null; | 1279 | m_ObjectInstArray[instance.m_PartUUID] = null; |
1310 | } | 1280 | } |
@@ -1312,12 +1282,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1312 | m_LockedDict = "~RegisterInstance"; | 1282 | m_LockedDict = "~RegisterInstance"; |
1313 | } | 1283 | } |
1314 | 1284 | ||
1315 | /* | 1285 | // Compile and load it. |
1316 | * Compile and load it. | 1286 | lock (m_ScriptErrors) |
1317 | */ | ||
1318 | lock (m_ScriptErrors) { | ||
1319 | m_ScriptErrors.Remove (instance.m_ItemID); | 1287 | m_ScriptErrors.Remove (instance.m_ItemID); |
1320 | } | 1288 | |
1321 | LoadThreadWork (instance); | 1289 | LoadThreadWork (instance); |
1322 | } | 1290 | } |
1323 | 1291 | ||
@@ -1326,17 +1294,20 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1326 | */ | 1294 | */ |
1327 | private void LoadThreadWork (XMRInstance instance) | 1295 | private void LoadThreadWork (XMRInstance instance) |
1328 | { | 1296 | { |
1329 | /* | 1297 | // Compile and load the script in memory. |
1330 | * Compile and load the script in memory. | 1298 | |
1331 | */ | ||
1332 | ArrayList errors = new ArrayList(); | 1299 | ArrayList errors = new ArrayList(); |
1333 | Exception initerr = null; | 1300 | Exception initerr = null; |
1334 | try { | 1301 | try |
1302 | { | ||
1335 | instance.Initialize(this, m_ScriptBasePath, m_StackSize, m_HeapSize, errors); | 1303 | instance.Initialize(this, m_ScriptBasePath, m_StackSize, m_HeapSize, errors); |
1336 | } catch (Exception e1) { | 1304 | } |
1305 | catch (Exception e1) | ||
1306 | { | ||
1337 | initerr = e1; | 1307 | initerr = e1; |
1338 | } | 1308 | } |
1339 | if ((initerr != null) && !instance.m_ForceRecomp) { | 1309 | if ((initerr != null) && !instance.m_ForceRecomp) |
1310 | { | ||
1340 | UUID itemID = instance.m_ItemID; | 1311 | UUID itemID = instance.m_ItemID; |
1341 | Verbose ("[XMREngine]: {0}/{2} first load failed ({1}), retrying after recompile", | 1312 | Verbose ("[XMREngine]: {0}/{2} first load failed ({1}), retrying after recompile", |
1342 | itemID.ToString(), initerr.Message, instance.m_Item.AssetID.ToString()); | 1313 | itemID.ToString(), initerr.Message, instance.m_Item.AssetID.ToString()); |
@@ -1344,62 +1315,66 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1344 | initerr = null; | 1315 | initerr = null; |
1345 | errors = new ArrayList(); | 1316 | errors = new ArrayList(); |
1346 | instance.m_ForceRecomp = true; | 1317 | instance.m_ForceRecomp = true; |
1347 | try { | 1318 | try |
1319 | { | ||
1348 | instance.Initialize(this, m_ScriptBasePath, m_StackSize, m_HeapSize, errors); | 1320 | instance.Initialize(this, m_ScriptBasePath, m_StackSize, m_HeapSize, errors); |
1349 | } catch (Exception e2) { | 1321 | } |
1322 | catch (Exception e2) | ||
1323 | { | ||
1350 | initerr = e2; | 1324 | initerr = e2; |
1351 | } | 1325 | } |
1352 | } | 1326 | } |
1353 | if (initerr != null) { | 1327 | if (initerr != null) |
1328 | { | ||
1354 | UUID itemID = instance.m_ItemID; | 1329 | UUID itemID = instance.m_ItemID; |
1355 | Verbose ("[XMREngine]: Error starting script {0}/{2}: {1}", | 1330 | Verbose ("[XMREngine]: Error starting script {0}/{2}: {1}", |
1356 | itemID.ToString(), initerr.Message, instance.m_Item.AssetID.ToString()); | 1331 | itemID.ToString(), initerr.Message, instance.m_Item.AssetID.ToString()); |
1357 | if (initerr.Message != "compilation errors") { | 1332 | if (initerr.Message != "compilation errors") |
1333 | { | ||
1358 | Verbose ("[XMREngine]: - " + instance.m_Part.GetWorldPosition () + " " + instance.m_DescName); | 1334 | Verbose ("[XMREngine]: - " + instance.m_Part.GetWorldPosition () + " " + instance.m_DescName); |
1359 | Verbose ("[XMREngine]: exception:\n{0}", initerr.ToString()); | 1335 | Verbose ("[XMREngine]: exception:\n{0}", initerr.ToString()); |
1360 | } | 1336 | } |
1361 | 1337 | ||
1362 | OnRemoveScript (0, itemID); | 1338 | OnRemoveScript (0, itemID); |
1363 | 1339 | ||
1364 | /* | 1340 | // Post errors where GetScriptErrors() can see them. |
1365 | * Post errors where GetScriptErrors() can see them. | 1341 | |
1366 | */ | 1342 | if (errors.Count == 0) |
1367 | if (errors.Count == 0) { | ||
1368 | errors.Add(initerr.Message); | 1343 | errors.Add(initerr.Message); |
1369 | } else { | 1344 | else |
1370 | foreach (Object err in errors) { | 1345 | { |
1346 | foreach (Object err in errors) | ||
1347 | { | ||
1371 | if (m_ScriptDebug) | 1348 | if (m_ScriptDebug) |
1372 | m_log.DebugFormat ("[XMREngine]: {0}", err.ToString()); | 1349 | m_log.DebugFormat ("[XMREngine]: {0}", err.ToString()); |
1373 | } | 1350 | } |
1374 | } | 1351 | } |
1375 | lock (m_ScriptErrors) { | 1352 | |
1353 | lock (m_ScriptErrors) | ||
1376 | m_ScriptErrors[instance.m_ItemID] = errors; | 1354 | m_ScriptErrors[instance.m_ItemID] = errors; |
1377 | } | ||
1378 | 1355 | ||
1379 | return; | 1356 | return; |
1380 | } | 1357 | } |
1381 | 1358 | ||
1382 | /* | 1359 | // Tell GetScriptErrors() that we have finished compiling/loading |
1383 | * Tell GetScriptErrors() that we have finished compiling/loading | 1360 | // successfully (by posting a 0 element array). |
1384 | * successfully (by posting a 0 element array). | 1361 | lock (m_ScriptErrors) |
1385 | */ | 1362 | { |
1386 | lock (m_ScriptErrors) { | ||
1387 | if (instance.m_IState != XMRInstState.CONSTRUCT) throw new Exception("bad state"); | 1363 | if (instance.m_IState != XMRInstState.CONSTRUCT) throw new Exception("bad state"); |
1388 | m_ScriptErrors[instance.m_ItemID] = noScriptErrors; | 1364 | m_ScriptErrors[instance.m_ItemID] = noScriptErrors; |
1389 | } | 1365 | } |
1390 | 1366 | ||
1391 | /* | 1367 | // Transition from CONSTRUCT->ONSTARTQ and give to RunScriptThread(). |
1392 | * Transition from CONSTRUCT->ONSTARTQ and give to RunScriptThread(). | 1368 | // Put it on the start queue so it will run any queued event handlers, |
1393 | * Put it on the start queue so it will run any queued event handlers, | 1369 | // such as state_entry() or on_rez(). If there aren't any queued, it |
1394 | * such as state_entry() or on_rez(). If there aren't any queued, it | 1370 | // will just go to idle state when RunOne() tries to dequeue an event. |
1395 | * will just go to idle state when RunOne() tries to dequeue an event. | 1371 | lock (instance.m_QueueLock) |
1396 | */ | 1372 | { |
1397 | lock (instance.m_QueueLock) { | 1373 | if (instance.m_IState != XMRInstState.CONSTRUCT) |
1398 | if (instance.m_IState != XMRInstState.CONSTRUCT) throw new Exception("bad state"); | 1374 | throw new Exception("bad state"); |
1399 | instance.m_IState = XMRInstState.ONSTARTQ; | 1375 | instance.m_IState = XMRInstState.ONSTARTQ; |
1400 | if (!instance.m_Running) { | 1376 | if (!instance.m_Running) |
1401 | instance.EmptyEventQueues (); | 1377 | instance.EmptyEventQueues (); |
1402 | } | ||
1403 | } | 1378 | } |
1404 | QueueToStart(instance); | 1379 | QueueToStart(instance); |
1405 | } | 1380 | } |
@@ -1408,66 +1383,57 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1408 | { | 1383 | { |
1409 | TraceCalls("[XMREngine]: OnRemoveScript(...,{0})", itemID.ToString()); | 1384 | TraceCalls("[XMREngine]: OnRemoveScript(...,{0})", itemID.ToString()); |
1410 | 1385 | ||
1411 | /* | 1386 | // Remove from our list of known scripts. |
1412 | * Remove from our list of known scripts. | 1387 | // After this, no more events can queue because we won't be |
1413 | * After this, no more events can queue because we won't be | 1388 | // able to translate the itemID to an XMRInstance pointer. |
1414 | * able to translate the itemID to an XMRInstance pointer. | 1389 | |
1415 | */ | ||
1416 | XMRInstance instance = null; | 1390 | XMRInstance instance = null; |
1417 | lock (m_InstancesDict) | 1391 | lock (m_InstancesDict) |
1418 | { | 1392 | { |
1419 | m_LockedDict = "OnRemoveScript:" + itemID.ToString(); | 1393 | m_LockedDict = "OnRemoveScript:" + itemID.ToString(); |
1420 | 1394 | ||
1421 | /* | 1395 | // Tell the instance to free off everything it can. |
1422 | * Tell the instance to free off everything it can. | 1396 | |
1423 | */ | ||
1424 | if (!m_InstancesDict.TryGetValue(itemID, out instance)) | 1397 | if (!m_InstancesDict.TryGetValue(itemID, out instance)) |
1425 | { | 1398 | { |
1426 | m_LockedDict = "~OnRemoveScript"; | 1399 | m_LockedDict = "~OnRemoveScript"; |
1427 | return; | 1400 | return; |
1428 | } | 1401 | } |
1429 | 1402 | ||
1430 | /* | 1403 | // Tell it to stop executing anything. |
1431 | * Tell it to stop executing anything. | ||
1432 | */ | ||
1433 | instance.suspendOnCheckRunHold = true; | 1404 | instance.suspendOnCheckRunHold = true; |
1434 | 1405 | ||
1435 | /* | 1406 | // Remove it from our list of known script instances |
1436 | * Remove it from our list of known script instances | 1407 | // mostly so no more events can queue to it. |
1437 | * mostly so no more events can queue to it. | ||
1438 | */ | ||
1439 | m_InstancesDict.Remove(itemID); | 1408 | m_InstancesDict.Remove(itemID); |
1440 | 1409 | ||
1441 | List<UUID> itemIDList; | 1410 | List<UUID> itemIDList; |
1442 | if (m_ObjectItemList.TryGetValue (instance.m_PartUUID, out itemIDList)) { | 1411 | if (m_ObjectItemList.TryGetValue (instance.m_PartUUID, out itemIDList)) |
1412 | { | ||
1443 | itemIDList.Remove(itemID); | 1413 | itemIDList.Remove(itemID); |
1444 | if (itemIDList.Count == 0) { | 1414 | if (itemIDList.Count == 0) |
1415 | { | ||
1445 | m_ObjectItemList.Remove(instance.m_PartUUID); | 1416 | m_ObjectItemList.Remove(instance.m_PartUUID); |
1446 | m_ObjectInstArray.Remove(instance.m_PartUUID); | 1417 | m_ObjectInstArray.Remove(instance.m_PartUUID); |
1447 | } else { | ||
1448 | m_ObjectInstArray[instance.m_PartUUID] = null; | ||
1449 | } | 1418 | } |
1419 | else | ||
1420 | m_ObjectInstArray[instance.m_PartUUID] = null; | ||
1450 | } | 1421 | } |
1451 | 1422 | ||
1452 | /* | 1423 | // Delete the .state file as any needed contents were fetched with GetXMLState() |
1453 | * Delete the .state file as any needed contents were fetched with GetXMLState() | 1424 | // and stored on the database server. |
1454 | * and stored on the database server. | ||
1455 | */ | ||
1456 | string stateFileName = XMRInstance.GetStateFileName(m_ScriptBasePath, itemID); | 1425 | string stateFileName = XMRInstance.GetStateFileName(m_ScriptBasePath, itemID); |
1457 | File.Delete(stateFileName); | 1426 | File.Delete(stateFileName); |
1458 | 1427 | ||
1459 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; | 1428 | ScriptRemoved handlerScriptRemoved = OnScriptRemoved; |
1460 | if (handlerScriptRemoved != null) { | 1429 | if (handlerScriptRemoved != null) |
1461 | handlerScriptRemoved(itemID); | 1430 | handlerScriptRemoved(itemID); |
1462 | } | ||
1463 | 1431 | ||
1464 | m_LockedDict = "~~OnRemoveScript"; | 1432 | m_LockedDict = "~~OnRemoveScript"; |
1465 | } | 1433 | } |
1466 | 1434 | ||
1467 | /* | 1435 | // Free off its stack and fun things like that. |
1468 | * Free off its stack and fun things like that. | 1436 | // If it is running, abort it. |
1469 | * If it is running, abort it. | ||
1470 | */ | ||
1471 | instance.Dispose (); | 1437 | instance.Dispose (); |
1472 | } | 1438 | } |
1473 | 1439 | ||
@@ -1480,31 +1446,33 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1480 | public void OnStartScript(uint localID, UUID itemID) | 1446 | public void OnStartScript(uint localID, UUID itemID) |
1481 | { | 1447 | { |
1482 | XMRInstance instance = GetInstance (itemID); | 1448 | XMRInstance instance = GetInstance (itemID); |
1483 | if (instance != null) { | 1449 | if (instance != null) |
1484 | instance.Running = true; | 1450 | instance.Running = true; |
1485 | } | ||
1486 | } | 1451 | } |
1487 | 1452 | ||
1488 | public void OnStopScript(uint localID, UUID itemID) | 1453 | public void OnStopScript(uint localID, UUID itemID) |
1489 | { | 1454 | { |
1490 | XMRInstance instance = GetInstance (itemID); | 1455 | XMRInstance instance = GetInstance (itemID); |
1491 | if (instance != null) { | 1456 | if (instance != null) |
1492 | instance.Running = false; | 1457 | instance.Running = false; |
1493 | } | ||
1494 | } | 1458 | } |
1495 | 1459 | ||
1496 | public void OnGetScriptRunning(IClientAPI controllingClient, | 1460 | public void OnGetScriptRunning(IClientAPI controllingClient, |
1497 | UUID objectID, UUID itemID) | 1461 | UUID objectID, UUID itemID) |
1498 | { | 1462 | { |
1499 | XMRInstance instance = GetInstance (itemID); | 1463 | XMRInstance instance = GetInstance (itemID); |
1500 | if (instance != null) { | 1464 | if (instance != null) |
1465 | { | ||
1501 | TraceCalls("[XMREngine]: XMREngine.OnGetScriptRunning({0},{1})", objectID.ToString(), itemID.ToString()); | 1466 | TraceCalls("[XMREngine]: XMREngine.OnGetScriptRunning({0},{1})", objectID.ToString(), itemID.ToString()); |
1502 | 1467 | ||
1503 | IEventQueue eq = World.RequestModuleInterface<IEventQueue>(); | 1468 | IEventQueue eq = World.RequestModuleInterface<IEventQueue>(); |
1504 | if (eq == null) { | 1469 | if (eq == null) |
1470 | { | ||
1505 | controllingClient.SendScriptRunningReply(objectID, itemID, | 1471 | controllingClient.SendScriptRunningReply(objectID, itemID, |
1506 | instance.Running); | 1472 | instance.Running); |
1507 | } else { | 1473 | } |
1474 | else | ||
1475 | { | ||
1508 | eq.Enqueue(EventQueueHelper.ScriptRunningReplyEvent(objectID, | 1476 | eq.Enqueue(EventQueueHelper.ScriptRunningReplyEvent(objectID, |
1509 | itemID, instance.Running, true), | 1477 | itemID, instance.Running, true), |
1510 | controllingClient.AgentId); | 1478 | controllingClient.AgentId); |
@@ -1515,7 +1483,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1515 | public bool HasScript(UUID itemID, out bool running) | 1483 | public bool HasScript(UUID itemID, out bool running) |
1516 | { | 1484 | { |
1517 | XMRInstance instance = GetInstance (itemID); | 1485 | XMRInstance instance = GetInstance (itemID); |
1518 | if (instance == null) { | 1486 | if (instance == null) |
1487 | { | ||
1519 | running = true; | 1488 | running = true; |
1520 | return false; | 1489 | return false; |
1521 | } | 1490 | } |
@@ -1529,9 +1498,11 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1529 | */ | 1498 | */ |
1530 | private void OnFrame () | 1499 | private void OnFrame () |
1531 | { | 1500 | { |
1532 | if (m_FrameUpdateList != null) { | 1501 | if (m_FrameUpdateList != null) |
1502 | { | ||
1533 | ThreadStart frameupdates; | 1503 | ThreadStart frameupdates; |
1534 | lock (m_FrameUpdateLock) { | 1504 | lock (m_FrameUpdateLock) |
1505 | { | ||
1535 | frameupdates = m_FrameUpdateList; | 1506 | frameupdates = m_FrameUpdateList; |
1536 | m_FrameUpdateList = null; | 1507 | m_FrameUpdateList = null; |
1537 | } | 1508 | } |
@@ -1545,9 +1516,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1545 | */ | 1516 | */ |
1546 | public void AddOnFrameUpdate (ThreadStart thunk) | 1517 | public void AddOnFrameUpdate (ThreadStart thunk) |
1547 | { | 1518 | { |
1548 | lock (m_FrameUpdateLock) { | 1519 | lock (m_FrameUpdateLock) |
1549 | m_FrameUpdateList += thunk; | 1520 | m_FrameUpdateList += thunk; |
1550 | } | ||
1551 | } | 1521 | } |
1552 | 1522 | ||
1553 | /** | 1523 | /** |
@@ -1570,7 +1540,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1570 | */ | 1540 | */ |
1571 | public void QueueToStart(XMRInstance inst) | 1541 | public void QueueToStart(XMRInstance inst) |
1572 | { | 1542 | { |
1573 | lock (m_StartQueue) { | 1543 | lock (m_StartQueue) |
1544 | { | ||
1574 | if (inst.m_IState != XMRInstState.ONSTARTQ) throw new Exception("bad state"); | 1545 | if (inst.m_IState != XMRInstState.ONSTARTQ) throw new Exception("bad state"); |
1575 | m_StartQueue.InsertTail(inst); | 1546 | m_StartQueue.InsertTail(inst); |
1576 | } | 1547 | } |
@@ -1582,28 +1553,25 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1582 | */ | 1553 | */ |
1583 | public void WakeFromSleep(XMRInstance inst) | 1554 | public void WakeFromSleep(XMRInstance inst) |
1584 | { | 1555 | { |
1585 | /* | 1556 | // Remove from sleep queue unless someone else already woke it. |
1586 | * Remove from sleep queue unless someone else already woke it. | 1557 | lock (m_SleepQueue) |
1587 | */ | 1558 | { |
1588 | lock (m_SleepQueue) { | 1559 | if (inst.m_IState != XMRInstState.ONSLEEPQ) |
1589 | if (inst.m_IState != XMRInstState.ONSLEEPQ) { | ||
1590 | return; | 1560 | return; |
1591 | } | 1561 | |
1592 | m_SleepQueue.Remove(inst); | 1562 | m_SleepQueue.Remove(inst); |
1593 | inst.m_IState = XMRInstState.REMDFROMSLPQ; | 1563 | inst.m_IState = XMRInstState.REMDFROMSLPQ; |
1594 | } | 1564 | } |
1595 | 1565 | ||
1596 | /* | 1566 | // Put on end of list of scripts that are ready to run. |
1597 | * Put on end of list of scripts that are ready to run. | 1567 | lock (m_YieldQueue) |
1598 | */ | 1568 | { |
1599 | lock (m_YieldQueue) { | ||
1600 | inst.m_IState = XMRInstState.ONYIELDQ; | 1569 | inst.m_IState = XMRInstState.ONYIELDQ; |
1601 | m_YieldQueue.InsertTail(inst); | 1570 | m_YieldQueue.InsertTail(inst); |
1602 | } | 1571 | } |
1603 | 1572 | ||
1604 | /* | 1573 | |
1605 | * Make sure the OS thread is running so it will see the script. | 1574 | // Make sure the OS thread is running so it will see the script. |
1606 | */ | ||
1607 | XMRScriptThread.WakeUpOne(); | 1575 | XMRScriptThread.WakeUpOne(); |
1608 | } | 1576 | } |
1609 | 1577 | ||
@@ -1616,96 +1584,89 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1616 | */ | 1584 | */ |
1617 | public void HandleNewIState(XMRInstance inst, XMRInstState newIState) | 1585 | public void HandleNewIState(XMRInstance inst, XMRInstState newIState) |
1618 | { | 1586 | { |
1619 | /* | ||
1620 | * RunOne() should have left the instance in RUNNING state. | ||
1621 | */ | ||
1622 | if (inst.m_IState != XMRInstState.RUNNING) throw new Exception("bad state"); | ||
1623 | 1587 | ||
1624 | /* | 1588 | // RunOne() should have left the instance in RUNNING state. |
1625 | * Now see what RunOne() wants us to do with the instance next. | 1589 | if (inst.m_IState != XMRInstState.RUNNING) |
1626 | */ | 1590 | throw new Exception("bad state"); |
1627 | switch (newIState) { | 1591 | |
1628 | 1592 | ||
1629 | /* | 1593 | // Now see what RunOne() wants us to do with the instance next. |
1630 | * Instance has set m_SleepUntil to when it wants to sleep until. | 1594 | switch (newIState) |
1631 | * So insert instance in sleep queue by ascending wake time. | 1595 | { |
1632 | * Then wake the timer thread if this is the new first entry | 1596 | |
1633 | * so it will reset its timer. | 1597 | // Instance has set m_SleepUntil to when it wants to sleep until. |
1634 | */ | 1598 | // So insert instance in sleep queue by ascending wake time. |
1635 | case XMRInstState.ONSLEEPQ: { | 1599 | // Then wake the timer thread if this is the new first entry |
1636 | lock (m_SleepQueue) { | 1600 | // so it will reset its timer. |
1601 | case XMRInstState.ONSLEEPQ: | ||
1602 | lock (m_SleepQueue) | ||
1603 | { | ||
1637 | XMRInstance after; | 1604 | XMRInstance after; |
1638 | 1605 | ||
1639 | inst.m_IState = XMRInstState.ONSLEEPQ; | 1606 | inst.m_IState = XMRInstState.ONSLEEPQ; |
1640 | for (after = m_SleepQueue.PeekHead(); after != null; after = after.m_NextInst) { | 1607 | for (after = m_SleepQueue.PeekHead(); after != null; after = after.m_NextInst) |
1641 | if (after.m_SleepUntil > inst.m_SleepUntil) break; | 1608 | { |
1609 | if (after.m_SleepUntil > inst.m_SleepUntil) | ||
1610 | break; | ||
1642 | } | 1611 | } |
1643 | m_SleepQueue.InsertBefore(inst, after); | 1612 | m_SleepQueue.InsertBefore(inst, after); |
1644 | if (m_SleepQueue.PeekHead() == inst) { | 1613 | if (m_SleepQueue.PeekHead() == inst) |
1614 | { | ||
1645 | Monitor.Pulse (m_SleepQueue); | 1615 | Monitor.Pulse (m_SleepQueue); |
1646 | } | 1616 | } |
1647 | } | 1617 | } |
1648 | break; | 1618 | break; |
1649 | } | ||
1650 | 1619 | ||
1651 | /* | 1620 | // Instance just took a long time to run and got wacked by the |
1652 | * Instance just took a long time to run and got wacked by the | 1621 | // slicer. So put on end of yield queue to let someone else |
1653 | * slicer. So put on end of yield queue to let someone else | 1622 | // run. If there is no one else, it will run again right away. |
1654 | * run. If there is no one else, it will run again right away. | 1623 | case XMRInstState.ONYIELDQ: |
1655 | */ | 1624 | lock (m_YieldQueue) |
1656 | case XMRInstState.ONYIELDQ: { | 1625 | { |
1657 | lock (m_YieldQueue) { | ||
1658 | inst.m_IState = XMRInstState.ONYIELDQ; | 1626 | inst.m_IState = XMRInstState.ONYIELDQ; |
1659 | m_YieldQueue.InsertTail(inst); | 1627 | m_YieldQueue.InsertTail(inst); |
1660 | } | 1628 | } |
1661 | break; | 1629 | break; |
1662 | } | ||
1663 | 1630 | ||
1664 | /* | 1631 | // Instance finished executing an event handler. So if there is |
1665 | * Instance finished executing an event handler. So if there is | 1632 | // another event queued for it, put it on the start queue so it |
1666 | * another event queued for it, put it on the start queue so it | 1633 | // will process the new event. Otherwise, mark it idle and the |
1667 | * will process the new event. Otherwise, mark it idle and the | 1634 | // next event to queue to it will start it up. |
1668 | * next event to queue to it will start it up. | 1635 | case XMRInstState.FINISHED: |
1669 | */ | ||
1670 | case XMRInstState.FINISHED: { | ||
1671 | Monitor.Enter(inst.m_QueueLock); | 1636 | Monitor.Enter(inst.m_QueueLock); |
1672 | if (!inst.m_Suspended && (inst.m_EventQueue.Count > 0)) { | 1637 | if (!inst.m_Suspended && (inst.m_EventQueue.Count > 0)) |
1638 | { | ||
1673 | Monitor.Exit(inst.m_QueueLock); | 1639 | Monitor.Exit(inst.m_QueueLock); |
1674 | lock (m_StartQueue) { | 1640 | lock (m_StartQueue) |
1641 | { | ||
1675 | inst.m_IState = XMRInstState.ONSTARTQ; | 1642 | inst.m_IState = XMRInstState.ONSTARTQ; |
1676 | m_StartQueue.InsertTail (inst); | 1643 | m_StartQueue.InsertTail (inst); |
1677 | } | 1644 | } |
1678 | } else { | 1645 | } |
1646 | else | ||
1647 | { | ||
1679 | inst.m_IState = XMRInstState.IDLE; | 1648 | inst.m_IState = XMRInstState.IDLE; |
1680 | Monitor.Exit(inst.m_QueueLock); | 1649 | Monitor.Exit(inst.m_QueueLock); |
1681 | } | 1650 | } |
1682 | break; | 1651 | break; |
1683 | } | ||
1684 | 1652 | ||
1685 | /* | 1653 | // Its m_SuspendCount > 0. |
1686 | * Its m_SuspendCount > 0. | 1654 | // Don't put it on any queue and it won't run. |
1687 | * Don't put it on any queue and it won't run. | 1655 | // Since it's not IDLE, even queuing an event won't start it. |
1688 | * Since it's not IDLE, even queuing an event won't start it. | 1656 | case XMRInstState.SUSPENDED: |
1689 | */ | ||
1690 | case XMRInstState.SUSPENDED: { | ||
1691 | inst.m_IState = XMRInstState.SUSPENDED; | 1657 | inst.m_IState = XMRInstState.SUSPENDED; |
1692 | break; | 1658 | break; |
1693 | } | ||
1694 | 1659 | ||
1695 | /* | 1660 | // It has been disposed of. |
1696 | * It has been disposed of. | 1661 | // Just set the new state and all refs should theoretically drop off |
1697 | * Just set the new state and all refs should theoretically drop off | 1662 | // as the instance is no longer in any list. |
1698 | * as the instance is no longer in any list. | 1663 | case XMRInstState.DISPOSED: |
1699 | */ | ||
1700 | case XMRInstState.DISPOSED: { | ||
1701 | inst.m_IState = XMRInstState.DISPOSED; | 1664 | inst.m_IState = XMRInstState.DISPOSED; |
1702 | break; | 1665 | break; |
1703 | } | ||
1704 | 1666 | ||
1705 | /* | 1667 | // RunOne returned something bad. |
1706 | * RunOne returned something bad. | 1668 | default: |
1707 | */ | 1669 | throw new Exception("bad new state"); |
1708 | default: throw new Exception("bad new state"); | ||
1709 | } | 1670 | } |
1710 | } | 1671 | } |
1711 | 1672 | ||
@@ -1718,45 +1679,48 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1718 | int deltaMS; | 1679 | int deltaMS; |
1719 | XMRInstance inst; | 1680 | XMRInstance inst; |
1720 | 1681 | ||
1721 | while (true) { | 1682 | while (true) |
1722 | lock (m_SleepQueue) { | 1683 | { |
1684 | lock (m_SleepQueue) | ||
1685 | { | ||
1723 | 1686 | ||
1724 | /* | 1687 | // Wait here until there is a script on the timer queue that has expired. |
1725 | * Wait here until there is a script on the timer queue that has expired. | 1688 | while (true) |
1726 | */ | 1689 | { |
1727 | while (true) { | ||
1728 | UpdateMyThread (); | 1690 | UpdateMyThread (); |
1729 | if (m_Exiting) { | 1691 | if (m_Exiting) |
1692 | { | ||
1730 | MyThreadExiting (); | 1693 | MyThreadExiting (); |
1731 | return; | 1694 | return; |
1732 | } | 1695 | } |
1733 | inst = m_SleepQueue.PeekHead(); | 1696 | inst = m_SleepQueue.PeekHead(); |
1734 | if (inst == null) { | 1697 | if (inst == null) |
1698 | { | ||
1735 | Monitor.Wait (m_SleepQueue, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2); | 1699 | Monitor.Wait (m_SleepQueue, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2); |
1736 | continue; | 1700 | continue; |
1737 | } | 1701 | } |
1738 | if (inst.m_IState != XMRInstState.ONSLEEPQ) throw new Exception("bad state"); | 1702 | if (inst.m_IState != XMRInstState.ONSLEEPQ) throw new Exception("bad state"); |
1739 | deltaTS = (inst.m_SleepUntil - DateTime.UtcNow).TotalMilliseconds; | 1703 | deltaTS = (inst.m_SleepUntil - DateTime.UtcNow).TotalMilliseconds; |
1740 | if (deltaTS <= 0.0) break; | 1704 | if (deltaTS <= 0.0) |
1705 | break; | ||
1741 | deltaMS = Int32.MaxValue; | 1706 | deltaMS = Int32.MaxValue; |
1742 | if (deltaTS < Int32.MaxValue) deltaMS = (int)deltaTS; | 1707 | if (deltaTS < Int32.MaxValue) |
1743 | if (deltaMS > Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2) { | 1708 | deltaMS = (int)deltaTS; |
1709 | if (deltaMS > Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2) | ||
1710 | { | ||
1744 | deltaMS = Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2; | 1711 | deltaMS = Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2; |
1745 | } | 1712 | } |
1746 | Monitor.Wait (m_SleepQueue, deltaMS); | 1713 | Monitor.Wait (m_SleepQueue, deltaMS); |
1747 | } | 1714 | } |
1748 | 1715 | ||
1749 | /* | 1716 | // Remove the expired entry from the timer queue. |
1750 | * Remove the expired entry from the timer queue. | ||
1751 | */ | ||
1752 | m_SleepQueue.RemoveHead(); | 1717 | m_SleepQueue.RemoveHead(); |
1753 | inst.m_IState = XMRInstState.REMDFROMSLPQ; | 1718 | inst.m_IState = XMRInstState.REMDFROMSLPQ; |
1754 | } | 1719 | } |
1755 | 1720 | ||
1756 | /* | 1721 | // Post the script to the yield queue so it will run and wake a script thread to run it. |
1757 | * Post the script to the yield queue so it will run and wake a script thread to run it. | 1722 | lock (m_YieldQueue) |
1758 | */ | 1723 | { |
1759 | lock (m_YieldQueue) { | ||
1760 | inst.m_IState = XMRInstState.ONYIELDQ; | 1724 | inst.m_IState = XMRInstState.ONYIELDQ; |
1761 | m_YieldQueue.InsertTail(inst); | 1725 | m_YieldQueue.InsertTail(inst); |
1762 | } | 1726 | } |
@@ -1767,42 +1731,18 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1767 | /** | 1731 | /** |
1768 | * @brief Thread that runs a time slicer. | 1732 | * @brief Thread that runs a time slicer. |
1769 | */ | 1733 | */ |
1770 | /* | ||
1771 | private void RunSliceThread() | ||
1772 | { | ||
1773 | int ms = m_Config.GetInt ("TimeSlice", 50); | ||
1774 | while (!m_Exiting) { | ||
1775 | UpdateMyThread (); | ||
1776 | */ | ||
1777 | /* | ||
1778 | * Let script run for a little bit. | ||
1779 | */ | ||
1780 | // System.Threading.Thread.Sleep (ms); | ||
1781 | |||
1782 | /* | ||
1783 | * If some script is running, flag it to suspend | ||
1784 | * next time it calls CheckRun(). | ||
1785 | */ | ||
1786 | /* for (int i = 0; i < numThreadScriptWorkers; i ++) { | ||
1787 | XMRScriptThread st = m_ScriptThreads[i]; | ||
1788 | if (st != null) st.TimeSlice(); | ||
1789 | } | ||
1790 | } | ||
1791 | MyThreadExiting (); | ||
1792 | } | ||
1793 | */ | ||
1794 | public void Suspend(UUID itemID, int ms) | 1734 | public void Suspend(UUID itemID, int ms) |
1795 | { | 1735 | { |
1796 | XMRInstance instance = GetInstance (itemID); | 1736 | XMRInstance instance = GetInstance (itemID); |
1797 | if (instance != null) { | 1737 | if (instance != null) |
1798 | instance.Sleep(ms); | 1738 | instance.Sleep(ms); |
1799 | } | ||
1800 | } | 1739 | } |
1801 | 1740 | ||
1802 | public void Die(UUID itemID) | 1741 | public void Die(UUID itemID) |
1803 | { | 1742 | { |
1804 | XMRInstance instance = GetInstance (itemID); | 1743 | XMRInstance instance = GetInstance (itemID); |
1805 | if (instance != null) { | 1744 | if (instance != null) |
1745 | { | ||
1806 | TraceCalls("[XMREngine]: XMREngine.Die({0})", itemID.ToString()); | 1746 | TraceCalls("[XMREngine]: XMREngine.Die({0})", itemID.ToString()); |
1807 | instance.Die(); | 1747 | instance.Die(); |
1808 | } | 1748 | } |
@@ -1819,10 +1759,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1819 | public XMRInstance GetInstance(UUID itemID) | 1759 | public XMRInstance GetInstance(UUID itemID) |
1820 | { | 1760 | { |
1821 | XMRInstance instance; | 1761 | XMRInstance instance; |
1822 | lock (m_InstancesDict) { | 1762 | lock (m_InstancesDict) |
1823 | if (!m_InstancesDict.TryGetValue(itemID, out instance)) { | 1763 | { |
1764 | if (!m_InstancesDict.TryGetValue(itemID, out instance)) | ||
1824 | instance = null; | 1765 | instance = null; |
1825 | } | ||
1826 | } | 1766 | } |
1827 | return instance; | 1767 | return instance; |
1828 | } | 1768 | } |
@@ -1834,9 +1774,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1834 | { | 1774 | { |
1835 | XMRInstance[] instanceArray; | 1775 | XMRInstance[] instanceArray; |
1836 | 1776 | ||
1837 | lock (m_InstancesDict) { | 1777 | lock (m_InstancesDict) |
1838 | instanceArray = System.Linq.Enumerable.ToArray(m_InstancesDict.Values); | 1778 | instanceArray = System.Linq.Enumerable.ToArray(m_InstancesDict.Values); |
1839 | } | 1779 | |
1840 | foreach (XMRInstance ins in instanceArray) | 1780 | foreach (XMRInstance ins in instanceArray) |
1841 | { | 1781 | { |
1842 | // Don't save attachments | 1782 | // Don't save attachments |
@@ -1856,8 +1796,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1856 | { | 1796 | { |
1857 | ArrayList errors; | 1797 | ArrayList errors; |
1858 | 1798 | ||
1859 | lock (m_ScriptErrors) { | 1799 | lock (m_ScriptErrors) |
1860 | while (!m_ScriptErrors.TryGetValue (itemID, out errors)) { | 1800 | { |
1801 | while (!m_ScriptErrors.TryGetValue (itemID, out errors)) | ||
1802 | { | ||
1861 | Monitor.Wait (m_ScriptErrors); | 1803 | Monitor.Wait (m_ScriptErrors); |
1862 | } | 1804 | } |
1863 | m_ScriptErrors.Remove (itemID); | 1805 | m_ScriptErrors.Remove (itemID); |
@@ -1871,13 +1813,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1871 | public Dictionary<uint, float> GetObjectScriptsExecutionTimes () | 1813 | public Dictionary<uint, float> GetObjectScriptsExecutionTimes () |
1872 | { | 1814 | { |
1873 | Dictionary<uint, float> topScripts = new Dictionary<uint, float> (); | 1815 | Dictionary<uint, float> topScripts = new Dictionary<uint, float> (); |
1874 | lock (m_InstancesDict) { | 1816 | lock (m_InstancesDict) |
1875 | foreach (XMRInstance instance in m_InstancesDict.Values) { | 1817 | { |
1818 | foreach (XMRInstance instance in m_InstancesDict.Values) | ||
1819 | { | ||
1876 | uint rootLocalID = instance.m_Part.ParentGroup.LocalId; | 1820 | uint rootLocalID = instance.m_Part.ParentGroup.LocalId; |
1877 | float oldTotal; | 1821 | float oldTotal; |
1878 | if (!topScripts.TryGetValue (rootLocalID, out oldTotal)) { | 1822 | if (!topScripts.TryGetValue (rootLocalID, out oldTotal)) |
1879 | oldTotal = 0; | 1823 | oldTotal = 0; |
1880 | } | 1824 | |
1881 | topScripts[rootLocalID] = (float)instance.m_CPUTime + oldTotal; | 1825 | topScripts[rootLocalID] = (float)instance.m_CPUTime + oldTotal; |
1882 | } | 1826 | } |
1883 | } | 1827 | } |
@@ -1892,15 +1836,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1892 | */ | 1836 | */ |
1893 | public float GetScriptExecutionTime (List<UUID> itemIDs) | 1837 | public float GetScriptExecutionTime (List<UUID> itemIDs) |
1894 | { | 1838 | { |
1895 | if ((itemIDs == null) || (itemIDs.Count == 0)) { | 1839 | if ((itemIDs == null) || (itemIDs.Count == 0)) |
1896 | return 0; | 1840 | return 0; |
1897 | } | 1841 | |
1898 | float time = 0; | 1842 | float time = 0; |
1899 | foreach (UUID itemID in itemIDs) { | 1843 | foreach (UUID itemID in itemIDs) |
1844 | { | ||
1900 | XMRInstance instance = GetInstance (itemID); | 1845 | XMRInstance instance = GetInstance (itemID); |
1901 | if ((instance != null) && instance.Running) { | 1846 | if ((instance != null) && instance.Running) |
1902 | time += (float) instance.m_CPUTime; | 1847 | time += (float) instance.m_CPUTime; |
1903 | } | ||
1904 | } | 1848 | } |
1905 | return time; | 1849 | return time; |
1906 | } | 1850 | } |
@@ -1911,7 +1855,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1911 | public void SuspendScript(UUID itemID) | 1855 | public void SuspendScript(UUID itemID) |
1912 | { | 1856 | { |
1913 | XMRInstance instance = GetInstance (itemID); | 1857 | XMRInstance instance = GetInstance (itemID); |
1914 | if (instance != null) { | 1858 | if (instance != null) |
1859 | { | ||
1915 | TraceCalls("[XMREngine]: XMREngine.SuspendScript({0})", itemID.ToString()); | 1860 | TraceCalls("[XMREngine]: XMREngine.SuspendScript({0})", itemID.ToString()); |
1916 | instance.SuspendIt(); | 1861 | instance.SuspendIt(); |
1917 | } | 1862 | } |
@@ -1923,10 +1868,13 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1923 | public void ResumeScript(UUID itemID) | 1868 | public void ResumeScript(UUID itemID) |
1924 | { | 1869 | { |
1925 | XMRInstance instance = GetInstance (itemID); | 1870 | XMRInstance instance = GetInstance (itemID); |
1926 | if (instance != null) { | 1871 | if (instance != null) |
1872 | { | ||
1927 | TraceCalls("[XMREngine]: XMREngine.ResumeScript({0})", itemID.ToString()); | 1873 | TraceCalls("[XMREngine]: XMREngine.ResumeScript({0})", itemID.ToString()); |
1928 | instance.ResumeIt(); | 1874 | instance.ResumeIt(); |
1929 | } else { | 1875 | } |
1876 | else | ||
1877 | { | ||
1930 | // probably an XEngine script | 1878 | // probably an XEngine script |
1931 | } | 1879 | } |
1932 | } | 1880 | } |
@@ -1939,13 +1887,17 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1939 | { | 1887 | { |
1940 | List<UUID> itemIDList = m_ObjectItemList[partUUID]; | 1888 | List<UUID> itemIDList = m_ObjectItemList[partUUID]; |
1941 | int n = 0; | 1889 | int n = 0; |
1942 | foreach (UUID itemID in itemIDList) { | 1890 | foreach (UUID itemID in itemIDList) |
1943 | if (m_InstancesDict.ContainsKey (itemID)) n ++; | 1891 | { |
1892 | if (m_InstancesDict.ContainsKey(itemID)) | ||
1893 | n ++; | ||
1944 | } | 1894 | } |
1945 | XMRInstance[] a = new XMRInstance[n]; | 1895 | XMRInstance[] a = new XMRInstance[n]; |
1946 | n = 0; | 1896 | n = 0; |
1947 | foreach (UUID itemID in itemIDList) { | 1897 | foreach (UUID itemID in itemIDList) |
1948 | if (m_InstancesDict.TryGetValue (itemID, out a[n])) n ++; | 1898 | { |
1899 | if (m_InstancesDict.TryGetValue (itemID, out a[n])) | ||
1900 | n ++; | ||
1949 | } | 1901 | } |
1950 | m_ObjectInstArray[partUUID] = a; | 1902 | m_ObjectInstArray[partUUID] = a; |
1951 | return a; | 1903 | return a; |
@@ -1953,11 +1905,13 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1953 | 1905 | ||
1954 | public void TraceCalls (string format, params object[] args) | 1906 | public void TraceCalls (string format, params object[] args) |
1955 | { | 1907 | { |
1956 | if (m_TraceCalls) m_log.DebugFormat (format, args); | 1908 | if (m_TraceCalls) |
1909 | m_log.DebugFormat (format, args); | ||
1957 | } | 1910 | } |
1958 | public void Verbose (string format, params object[] args) | 1911 | public void Verbose (string format, params object[] args) |
1959 | { | 1912 | { |
1960 | if (m_Verbose) m_log.DebugFormat (format, args); | 1913 | if (m_Verbose) |
1914 | m_log.DebugFormat (format, args); | ||
1961 | } | 1915 | } |
1962 | 1916 | ||
1963 | /** | 1917 | /** |