diff options
author | UbitUmarov | 2018-02-07 10:26:20 +0000 |
---|---|---|
committer | UbitUmarov | 2018-02-07 10:26:20 +0000 |
commit | 53a910e3e5add262a4fee1f73aad7419f9d150b5 (patch) | |
tree | ed41e3a2014bbf5c7f1977279a16315be1aafed2 /OpenSim/Region/ScriptEngine/XMREngine/XMREngine.cs | |
parent | due credits even if code goes away (diff) | |
download | opensim-SC-53a910e3e5add262a4fee1f73aad7419f9d150b5.zip opensim-SC-53a910e3e5add262a4fee1f73aad7419f9d150b5.tar.gz opensim-SC-53a910e3e5add262a4fee1f73aad7419f9d150b5.tar.bz2 opensim-SC-53a910e3e5add262a4fee1f73aad7419f9d150b5.tar.xz |
some more code from mrieker for system threads, give up of all the other mono dependent theading models only availble for linux (and possible not all platforms). This only has impact on micro-threading switching, and this only happens on long events and only every 60ms, aditionally we do remove a totally extra set of threads (that could grow in a uncontroled way on win) and their hanshake with main ones. This may of course be even more broken now :P
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 | /** |