diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
8 files changed, 332 insertions, 435 deletions
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptInlines.cs b/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptInlines.cs index dc00001..fcb4b66 100644 --- a/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptInlines.cs +++ b/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptInlines.cs | |||
@@ -589,11 +589,11 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
589 | * @brief Generate code for the usual ll...() functions. | 589 | * @brief Generate code for the usual ll...() functions. |
590 | */ | 590 | */ |
591 | public class TokenDeclInline_BEApi : TokenDeclInline { | 591 | public class TokenDeclInline_BEApi : TokenDeclInline { |
592 | private static readonly MethodInfo fixLLParcelMediaQuery = ScriptCodeGen.GetStaticMethod | 592 | // private static readonly MethodInfo fixLLParcelMediaQuery = ScriptCodeGen.GetStaticMethod |
593 | (typeof (XMRInstAbstract), "FixLLParcelMediaQuery", new Type[] { typeof (LSL_List) }); | 593 | // (typeof (XMRInstAbstract), "FixLLParcelMediaQuery", new Type[] { typeof (LSL_List) }); |
594 | 594 | ||
595 | private static readonly MethodInfo fixLLParcelMediaCommandList = ScriptCodeGen.GetStaticMethod | 595 | // private static readonly MethodInfo fixLLParcelMediaCommandList = ScriptCodeGen.GetStaticMethod |
596 | (typeof (XMRInstAbstract), "FixLLParcelMediaCommandList", new Type[] { typeof (LSL_List) }); | 596 | // (typeof (XMRInstAbstract), "FixLLParcelMediaCommandList", new Type[] { typeof (LSL_List) }); |
597 | 597 | ||
598 | public bool doCheckRun; | 598 | public bool doCheckRun; |
599 | private FieldInfo apiContextField; | 599 | private FieldInfo apiContextField; |
@@ -626,39 +626,41 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
626 | */ | 626 | */ |
627 | public override void CodeGen (ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args) | 627 | public override void CodeGen (ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args) |
628 | { | 628 | { |
629 | if (isTaggedCallsCheckRun) { // see if 'xmr' method that calls CheckRun() internally | 629 | if (isTaggedCallsCheckRun) |
630 | new ScriptCodeGen.CallLabel (scg, errorAt); // if so, put a call label immediately before it | 630 | { // see if 'xmr' method that calls CheckRun() internally |
631 | // .. so restoring the frame will jump immediately to the | 631 | new ScriptCodeGen.CallLabel (scg, errorAt); // if so, put a call label immediately before it |
632 | // .. call without re-executing any code before this | 632 | // .. so restoring the frame will jump immediately to the |
633 | // .. call without re-executing any code before this | ||
633 | } | 634 | } |
634 | if (!methInfo.IsStatic) { | 635 | if (!methInfo.IsStatic) |
636 | { | ||
635 | scg.PushXMRInst (); // XMRInstanceSuperType pointer | 637 | scg.PushXMRInst (); // XMRInstanceSuperType pointer |
636 | if (apiContextField != null) { | 638 | if (apiContextField != null) // 'this' pointer for API function |
637 | scg.ilGen.Emit (errorAt, OpCodes.Ldfld, apiContextField); | 639 | scg.ilGen.Emit (errorAt, OpCodes.Ldfld, apiContextField); |
638 | // 'this' pointer for API function | 640 | |
639 | } | ||
640 | } | 641 | } |
641 | for (int i = 0; i < args.Length; i ++) { // push arguments, boxing/unboxing as needed | 642 | for (int i = 0; i < args.Length; i ++) // push arguments, boxing/unboxing as needed |
642 | args[i].PushVal (scg, errorAt, argDecl.types[i]); | 643 | args[i].PushVal (scg, errorAt, argDecl.types[i]); |
643 | } | 644 | |
644 | if (methInfo.Name == "llParcelMediaQuery") { | 645 | // this should not be needed |
645 | scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaQuery); | 646 | // if (methInfo.Name == "llParcelMediaQuery") { |
646 | } | 647 | // scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaQuery); |
647 | if (methInfo.Name == "llParcelMediaCommandList") { | 648 | // } |
648 | scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaCommandList); | 649 | // this should not be needed |
649 | } | 650 | // if (methInfo.Name == "llParcelMediaCommandList") { |
650 | if (methInfo.IsVirtual) { // call API function | 651 | // scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaCommandList); |
652 | // } | ||
653 | if (methInfo.IsVirtual) // call API function | ||
651 | scg.ilGen.Emit (errorAt, OpCodes.Callvirt, methInfo); | 654 | scg.ilGen.Emit (errorAt, OpCodes.Callvirt, methInfo); |
652 | } else { | 655 | else |
653 | scg.ilGen.Emit (errorAt, OpCodes.Call, methInfo); | 656 | scg.ilGen.Emit (errorAt, OpCodes.Call, methInfo); |
654 | } | 657 | |
655 | result.Pop (scg, errorAt, retType); // pop result, boxing/unboxing as needed | 658 | result.Pop (scg, errorAt, retType); // pop result, boxing/unboxing as needed |
656 | if (isTaggedCallsCheckRun) { | 659 | if (isTaggedCallsCheckRun) |
657 | scg.openCallLabel = null; | 660 | scg.openCallLabel = null; |
658 | } | 661 | |
659 | if (doCheckRun) { | 662 | if (doCheckRun) |
660 | scg.EmitCallCheckRun (errorAt, false); // maybe call CheckRun() | 663 | scg.EmitCallCheckRun (errorAt, false); // maybe call CheckRun() |
661 | } | ||
662 | } | 664 | } |
663 | } | 665 | } |
664 | } | 666 | } |
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMREngine.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMREngine.cs index aa8573c..7447f2f 100644 --- a/OpenSim/Region/ScriptEngine/XMREngine/XMREngine.cs +++ b/OpenSim/Region/ScriptEngine/XMREngine/XMREngine.cs | |||
@@ -99,7 +99,18 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
99 | new Dictionary<string,FieldInfo> (); | 99 | new Dictionary<string,FieldInfo> (); |
100 | private int m_StackSize; | 100 | private int m_StackSize; |
101 | private int m_HeapSize; | 101 | private int m_HeapSize; |
102 | |||
102 | private XMRScriptThread[] m_ScriptThreads; | 103 | private XMRScriptThread[] m_ScriptThreads; |
104 | private int m_WakeUpOne = 0; | ||
105 | public object m_WakeUpLock = new object(); | ||
106 | private Dictionary<Thread,XMRScriptThread> m_AllThreads = new Dictionary<Thread,XMRScriptThread> (); | ||
107 | |||
108 | private bool m_SuspendScriptThreadFlag = false; | ||
109 | /** | ||
110 | * @brief Something was just added to the Start or Yield queue so | ||
111 | * wake one of the XMRScriptThread instances to run it. | ||
112 | */ | ||
113 | |||
103 | private Thread m_SleepThread = null; | 114 | private Thread m_SleepThread = null; |
104 | private bool m_Exiting = false; | 115 | private bool m_Exiting = false; |
105 | 116 | ||
@@ -165,6 +176,36 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
165 | get { return scriptReferencedAssemblies; } | 176 | get { return scriptReferencedAssemblies; } |
166 | } | 177 | } |
167 | 178 | ||
179 | public void WakeUpOne() | ||
180 | { | ||
181 | lock (m_WakeUpLock) | ||
182 | { | ||
183 | m_WakeUpOne++; | ||
184 | Monitor.Pulse(m_WakeUpLock); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | public void AddThread(Thread thd, XMRScriptThread xthd) | ||
189 | { | ||
190 | lock(m_AllThreads) | ||
191 | m_AllThreads.Add(thd, xthd); | ||
192 | } | ||
193 | |||
194 | public void RemoveThread(Thread thd) | ||
195 | { | ||
196 | lock(m_AllThreads) | ||
197 | m_AllThreads.Remove(thd); | ||
198 | } | ||
199 | |||
200 | public XMRScriptThread CurrentScriptThread () | ||
201 | { | ||
202 | XMRScriptThread st; | ||
203 | lock (m_AllThreads) | ||
204 | m_AllThreads.TryGetValue (Thread.CurrentThread, out st); | ||
205 | |||
206 | return st; | ||
207 | } | ||
208 | |||
168 | public void Initialise(IConfigSource config) | 209 | public void Initialise(IConfigSource config) |
169 | { | 210 | { |
170 | TraceCalls("[XMREngine]: Initialize entry"); | 211 | TraceCalls("[XMREngine]: Initialize entry"); |
@@ -235,7 +276,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
235 | } | 276 | } |
236 | 277 | ||
237 | for (int i = 0; i < numThreadScriptWorkers; i ++) | 278 | for (int i = 0; i < numThreadScriptWorkers; i ++) |
238 | m_ScriptThreads[i] = new XMRScriptThread(this, i); | 279 | { |
280 | m_ScriptThreads[i] = new XMRScriptThread(this, i);; | ||
281 | } | ||
282 | |||
239 | 283 | ||
240 | m_SleepThread = StartMyThread(RunSleepThread, "xmrengine sleep", ThreadPriority.Normal); | 284 | m_SleepThread = StartMyThread(RunSleepThread, "xmrengine sleep", ThreadPriority.Normal); |
241 | 285 | ||
@@ -678,6 +722,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
678 | XMRScriptThread scriptThread = m_ScriptThreads[i]; | 722 | XMRScriptThread scriptThread = m_ScriptThreads[i]; |
679 | if (scriptThread != null) | 723 | if (scriptThread != null) |
680 | { | 724 | { |
725 | scriptThread.WakeUpScriptThread(); | ||
726 | Monitor.PulseAll (m_WakeUpLock); | ||
681 | scriptThread.Terminate(); | 727 | scriptThread.Terminate(); |
682 | m_ScriptThreads[i] = null; | 728 | m_ScriptThreads[i] = null; |
683 | } | 729 | } |
@@ -722,7 +768,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
722 | m_Scene.EventManager.TriggerEmptyScriptCompileQueue (0, ""); | 768 | m_Scene.EventManager.TriggerEmptyScriptCompileQueue (0, ""); |
723 | m_StartProcessing = true; | 769 | m_StartProcessing = true; |
724 | for (int i = 0; i < numThreadScriptWorkers; i ++) { | 770 | for (int i = 0; i < numThreadScriptWorkers; i ++) { |
725 | XMRScriptThread.WakeUpOne(); | 771 | WakeUpOne(); |
726 | } | 772 | } |
727 | m_log.Debug ("[XMREngine]: StartProcessing return"); | 773 | m_log.Debug ("[XMREngine]: StartProcessing return"); |
728 | } | 774 | } |
@@ -832,15 +878,18 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
832 | 878 | ||
833 | case "resume": | 879 | case "resume": |
834 | m_log.Info ("[XMREngine]: resuming scripts"); | 880 | m_log.Info ("[XMREngine]: resuming scripts"); |
881 | m_SuspendScriptThreadFlag = false; | ||
835 | for (int i = 0; i < numThreadScriptWorkers; i ++) | 882 | for (int i = 0; i < numThreadScriptWorkers; i ++) |
836 | m_ScriptThreads[i].ResumeThread(); | 883 | m_ScriptThreads[i].WakeUpScriptThread(); |
837 | 884 | Monitor.PulseAll(m_WakeUpLock); | |
838 | break; | 885 | break; |
839 | 886 | ||
840 | case "suspend": | 887 | case "suspend": |
841 | m_log.Info ("[XMREngine]: suspending scripts"); | 888 | m_log.Info ("[XMREngine]: suspending scripts"); |
889 | m_SuspendScriptThreadFlag = true; | ||
842 | for (int i = 0; i < numThreadScriptWorkers; i ++) | 890 | for (int i = 0; i < numThreadScriptWorkers; i ++) |
843 | m_ScriptThreads[i].SuspendThread(); | 891 | m_ScriptThreads[i].WakeUpScriptThread(); |
892 | Monitor.PulseAll(m_WakeUpLock); | ||
844 | break; | 893 | break; |
845 | 894 | ||
846 | case "tracecalls": | 895 | case "tracecalls": |
@@ -1545,7 +1594,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1545 | if (inst.m_IState != XMRInstState.ONSTARTQ) throw new Exception("bad state"); | 1594 | if (inst.m_IState != XMRInstState.ONSTARTQ) throw new Exception("bad state"); |
1546 | m_StartQueue.InsertTail(inst); | 1595 | m_StartQueue.InsertTail(inst); |
1547 | } | 1596 | } |
1548 | XMRScriptThread.WakeUpOne(); | 1597 | WakeUpOne(); |
1598 | } | ||
1599 | |||
1600 | public void QueueToTrunk(ThreadStart thds) | ||
1601 | { | ||
1602 | lock (m_WakeUpLock) | ||
1603 | m_ThunkQueue.Enqueue (thds); | ||
1604 | WakeUpOne(); | ||
1549 | } | 1605 | } |
1550 | 1606 | ||
1551 | /** | 1607 | /** |
@@ -1572,7 +1628,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1572 | 1628 | ||
1573 | 1629 | ||
1574 | // Make sure the OS thread is running so it will see the script. | 1630 | // Make sure the OS thread is running so it will see the script. |
1575 | XMRScriptThread.WakeUpOne(); | 1631 | WakeUpOne(); |
1576 | } | 1632 | } |
1577 | 1633 | ||
1578 | /** | 1634 | /** |
@@ -1724,7 +1780,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1724 | inst.m_IState = XMRInstState.ONYIELDQ; | 1780 | inst.m_IState = XMRInstState.ONYIELDQ; |
1725 | m_YieldQueue.InsertTail(inst); | 1781 | m_YieldQueue.InsertTail(inst); |
1726 | } | 1782 | } |
1727 | XMRScriptThread.WakeUpOne (); | 1783 | WakeUpOne (); |
1728 | } | 1784 | } |
1729 | } | 1785 | } |
1730 | 1786 | ||
@@ -1934,12 +1990,113 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
1934 | 1990 | ||
1935 | public static void UpdateMyThread () | 1991 | public static void UpdateMyThread () |
1936 | { | 1992 | { |
1937 | Watchdog.UpdateThread (); | 1993 | Watchdog.UpdateThread(); |
1938 | } | 1994 | } |
1939 | 1995 | ||
1940 | public static void MyThreadExiting () | 1996 | public static void MyThreadExiting () |
1941 | { | 1997 | { |
1942 | Watchdog.RemoveThread (true); | 1998 | Watchdog.RemoveThread(true); |
1999 | } | ||
2000 | |||
2001 | public void RunScriptThread(XMRScriptThread xthd) | ||
2002 | { | ||
2003 | XMRInstance inst; | ||
2004 | while (!m_Exiting) | ||
2005 | { | ||
2006 | Watchdog.UpdateThread(); | ||
2007 | |||
2008 | /* | ||
2009 | * Handle 'xmr resume/suspend' commands. | ||
2010 | */ | ||
2011 | if (m_SuspendScriptThreadFlag) | ||
2012 | { | ||
2013 | lock (m_WakeUpLock) | ||
2014 | { | ||
2015 | while (m_SuspendScriptThreadFlag && | ||
2016 | !m_Exiting && | ||
2017 | (m_ThunkQueue.Count == 0)) | ||
2018 | { | ||
2019 | Monitor.Wait (m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2); | ||
2020 | XMREngine.UpdateMyThread (); | ||
2021 | } | ||
2022 | } | ||
2023 | } | ||
2024 | |||
2025 | /* | ||
2026 | * Maybe there are some scripts waiting to be migrated in or out. | ||
2027 | */ | ||
2028 | ThreadStart thunk = null; | ||
2029 | lock (m_WakeUpLock) | ||
2030 | { | ||
2031 | if (m_ThunkQueue.Count > 0) | ||
2032 | thunk = m_ThunkQueue.Dequeue (); | ||
2033 | } | ||
2034 | if (thunk != null) | ||
2035 | { | ||
2036 | inst = (XMRInstance)thunk.Target; | ||
2037 | thunk (); | ||
2038 | if (m_Exiting || m_SuspendScriptThreadFlag) | ||
2039 | continue; | ||
2040 | } | ||
2041 | |||
2042 | if (m_StartProcessing) | ||
2043 | { | ||
2044 | // If event just queued to any idle scripts | ||
2045 | // start them right away. But only start so | ||
2046 | // many so we can make some progress on yield | ||
2047 | // queue. | ||
2048 | |||
2049 | int numStarts; | ||
2050 | for (numStarts = 5; -- numStarts >= 0;) | ||
2051 | { | ||
2052 | lock (m_StartQueue) | ||
2053 | { | ||
2054 | inst = m_StartQueue.RemoveHead(); | ||
2055 | } | ||
2056 | if (inst == null) break; | ||
2057 | if (inst.m_IState != XMRInstState.ONSTARTQ) throw new Exception("bad state"); | ||
2058 | xthd.RunInstance (inst); | ||
2059 | if (m_Exiting || m_SuspendScriptThreadFlag) | ||
2060 | continue; | ||
2061 | } | ||
2062 | |||
2063 | // If there is something to run, run it | ||
2064 | // then rescan from the beginning in case | ||
2065 | // a lot of things have changed meanwhile. | ||
2066 | // | ||
2067 | // These are considered lower priority than | ||
2068 | // m_StartQueue as they have been taking at | ||
2069 | // least one quantum of CPU time and event | ||
2070 | // handlers are supposed to be quick. | ||
2071 | |||
2072 | lock (m_YieldQueue) | ||
2073 | { | ||
2074 | inst = m_YieldQueue.RemoveHead(); | ||
2075 | } | ||
2076 | if (inst != null) | ||
2077 | { | ||
2078 | if (inst.m_IState != XMRInstState.ONYIELDQ) throw new Exception("bad state"); | ||
2079 | xthd.RunInstance(inst); | ||
2080 | numStarts = -1; | ||
2081 | } | ||
2082 | |||
2083 | // If we left something dangling in the m_StartQueue or m_YieldQueue, go back to check it. | ||
2084 | if (m_Exiting || numStarts < 0) | ||
2085 | continue; | ||
2086 | } | ||
2087 | |||
2088 | // Nothing to do, sleep. | ||
2089 | lock (m_WakeUpLock) | ||
2090 | { | ||
2091 | if (!xthd.m_WakeUpThis && (m_WakeUpOne <= 0) && !m_Exiting) | ||
2092 | Monitor.Wait(m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2); | ||
2093 | |||
2094 | xthd.m_WakeUpThis = false; | ||
2095 | if ((m_WakeUpOne > 0) && (--m_WakeUpOne > 0)) | ||
2096 | Monitor.Pulse (m_WakeUpLock); | ||
2097 | } | ||
2098 | } | ||
2099 | Watchdog.RemoveThread(true); | ||
1943 | } | 2100 | } |
1944 | } | 2101 | } |
1945 | } | 2102 | } |
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstAbstract.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstAbstract.cs index 82759ee..1ea05b6 100644 --- a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstAbstract.cs +++ b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstAbstract.cs | |||
@@ -491,11 +491,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
491 | { | 491 | { |
492 | if (this.newStateCode < 0) | 492 | if (this.newStateCode < 0) |
493 | { | 493 | { |
494 | // Process event given by 'stateCode' and 'eventCode'. | ||
495 | // The event handler should call CheckRun() as often as convenient. | ||
494 | 496 | ||
495 | /* | ||
496 | * Process event given by 'stateCode' and 'eventCode'. | ||
497 | * The event handler should call CheckRun() as often as convenient. | ||
498 | */ | ||
499 | int newState = this.stateCode; | 497 | int newState = this.stateCode; |
500 | seh = this.m_ObjCode.scriptEventHandlerTable[newState,(int)this.eventCode]; | 498 | seh = this.m_ObjCode.scriptEventHandlerTable[newState,(int)this.eventCode]; |
501 | if (seh != null) | 499 | if (seh != null) |
@@ -512,25 +510,19 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
512 | this.ehArgs = null; // we are done with them and no args for | 510 | this.ehArgs = null; // we are done with them and no args for |
513 | // exit_state()/enter_state() anyway | 511 | // exit_state()/enter_state() anyway |
514 | 512 | ||
515 | /* | 513 | // The usual case is no state change. |
516 | * The usual case is no state change. | 514 | // Even a 'state <samestate>;' statement has no effect except to exit out. |
517 | * Even a 'state <samestate>;' statement has no effect except to exit out. | 515 | // It does not execute the state_exit() or state_entry() handlers. |
518 | * It does not execute the state_exit() or state_entry() handlers. | 516 | // See http://wiki.secondlife.com/wiki/State |
519 | * See http://wiki.secondlife.com/wiki/State | ||
520 | */ | ||
521 | if (newState == this.stateCode) | 517 | if (newState == this.stateCode) |
522 | break; | 518 | break; |
523 | 519 | ||
524 | /* | 520 | // Save new state in a more permanent location in case we |
525 | * Save new state in a more permanent location in case we | 521 | // get serialized out while in the state_exit() handler. |
526 | * get serialized out while in the state_exit() handler. | ||
527 | */ | ||
528 | this.newStateCode = newState; | 522 | this.newStateCode = newState; |
529 | } | 523 | } |
530 | 524 | ||
531 | /* | 525 | // Call old state's state_exit() handler. |
532 | * Call old state's state_exit() handler. | ||
533 | */ | ||
534 | this.eventCode = ScriptEventCode.state_exit; | 526 | this.eventCode = ScriptEventCode.state_exit; |
535 | seh = this.m_ObjCode.scriptEventHandlerTable[this.stateCode,(int)ScriptEventCode.state_exit]; | 527 | seh = this.m_ObjCode.scriptEventHandlerTable[this.stateCode,(int)ScriptEventCode.state_exit]; |
536 | if (seh != null) | 528 | if (seh != null) |
@@ -545,27 +537,19 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
545 | } | 537 | } |
546 | } | 538 | } |
547 | 539 | ||
548 | /* | 540 | // Switch over to the new state's state_entry() handler. |
549 | * Switch over to the new state's state_entry() handler. | ||
550 | */ | ||
551 | this.stateCode = this.newStateCode; | 541 | this.stateCode = this.newStateCode; |
552 | this.eventCode = ScriptEventCode.state_entry; | 542 | this.eventCode = ScriptEventCode.state_entry; |
553 | this.newStateCode = -1; | 543 | this.newStateCode = -1; |
554 | 544 | ||
555 | /* | 545 | // Now that the old state can't possibly start any more activity, |
556 | * Now that the old state can't possibly start any more activity, | 546 | // cancel any listening handlers, etc, of the old state. |
557 | * cancel any listening handlers, etc, of the old state. | ||
558 | */ | ||
559 | this.StateChange (); | 547 | this.StateChange (); |
560 | 548 | ||
561 | /* | 549 | // Loop back to execute new state's state_entry() handler. |
562 | * Loop back to execute new state's state_entry() handler. | ||
563 | */ | ||
564 | } | 550 | } |
565 | 551 | ||
566 | /* | 552 | // Event no longer being processed. |
567 | * Event no longer being processed. | ||
568 | */ | ||
569 | this.eventCode = ScriptEventCode.None; | 553 | this.eventCode = ScriptEventCode.None; |
570 | } | 554 | } |
571 | 555 | ||
@@ -642,6 +626,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
642 | * @brief Convert all LSL_Integers in a list to System.Int32s, | 626 | * @brief Convert all LSL_Integers in a list to System.Int32s, |
643 | * as required by llParcelMediaQuery(). | 627 | * as required by llParcelMediaQuery(). |
644 | */ | 628 | */ |
629 | /* | ||
645 | public static LSL_List FixLLParcelMediaQuery (LSL_List oldlist) | 630 | public static LSL_List FixLLParcelMediaQuery (LSL_List oldlist) |
646 | { | 631 | { |
647 | object[] oldarray = oldlist.Data; | 632 | object[] oldarray = oldlist.Data; |
@@ -655,11 +640,12 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
655 | } | 640 | } |
656 | return new LSL_List (newarray); | 641 | return new LSL_List (newarray); |
657 | } | 642 | } |
658 | 643 | */ | |
659 | /** | 644 | /** |
660 | * @brief Convert *SOME* LSL_Integers in a list to System.Int32s, | 645 | * @brief Convert *SOME* LSL_Integers in a list to System.Int32s, |
661 | * as required by llParcelMediaCommandList(). | 646 | * as required by llParcelMediaCommandList(). |
662 | */ | 647 | */ |
648 | /* | ||
663 | public static LSL_List FixLLParcelMediaCommandList (LSL_List oldlist) | 649 | public static LSL_List FixLLParcelMediaCommandList (LSL_List oldlist) |
664 | { | 650 | { |
665 | object[] oldarray = oldlist.Data; | 651 | object[] oldarray = oldlist.Data; |
@@ -696,7 +682,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
696 | } | 682 | } |
697 | return new LSL_List (newarray); | 683 | return new LSL_List (newarray); |
698 | } | 684 | } |
699 | 685 | */ | |
700 | public static int xmrHashCode (int i) | 686 | public static int xmrHashCode (int i) |
701 | { | 687 | { |
702 | return i.GetHashCode (); | 688 | return i.GetHashCode (); |
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstBackend.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstBackend.cs index edbd5ce..a24036a 100644 --- a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstBackend.cs +++ b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstBackend.cs | |||
@@ -32,11 +32,6 @@ using OpenMetaverse; | |||
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.ScriptEngine.Shared; | 33 | using OpenSim.Region.ScriptEngine.Shared; |
34 | using OpenSim.Region.ScriptEngine.Shared.Api; | 34 | using OpenSim.Region.ScriptEngine.Shared.Api; |
35 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
36 | using OpenSim.Region.ScriptEngine.XMREngine; | ||
37 | using OpenSim.Region.Framework.Scenes; | ||
38 | using OpenSim.Region.Framework.Scenes.Scripting; | ||
39 | using OpenSim.Region.Framework.Interfaces; | ||
40 | using log4net; | 35 | using log4net; |
41 | 36 | ||
42 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; | 37 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; |
@@ -88,6 +83,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
88 | * -2: no av granted perms | 83 | * -2: no av granted perms |
89 | * -3: av not in region | 84 | * -3: av not in region |
90 | */ | 85 | */ |
86 | /* engines should not have own API | ||
91 | public int xmrSeatAvatar (bool owner) | 87 | public int xmrSeatAvatar (bool owner) |
92 | { | 88 | { |
93 | // Get avatar to be seated and make sure they have given us ANIMATION permission | 89 | // Get avatar to be seated and make sure they have given us ANIMATION permission |
@@ -118,7 +114,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
118 | presence.HandleAgentRequestSit (null, UUID.Zero, m_host.UUID, OpenMetaverse.Vector3.Zero); | 114 | presence.HandleAgentRequestSit (null, UUID.Zero, m_host.UUID, OpenMetaverse.Vector3.Zero); |
119 | return 0; | 115 | return 0; |
120 | } | 116 | } |
121 | 117 | */ | |
122 | /** | 118 | /** |
123 | * @brief llTeleportAgent() is broken in that if you pass it a landmark, | 119 | * @brief llTeleportAgent() is broken in that if you pass it a landmark, |
124 | * it still subjects the position to spawn points, as it always | 120 | * it still subjects the position to spawn points, as it always |
@@ -129,6 +125,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
129 | * @param landmark = inventory name or UUID of a landmark object | 125 | * @param landmark = inventory name or UUID of a landmark object |
130 | * @param lookat = looking direction after teleport | 126 | * @param lookat = looking direction after teleport |
131 | */ | 127 | */ |
128 | /* engines should not have own API | ||
132 | public void xmrTeleportAgent2Landmark (string agent, string landmark, LSL_Vector lookat) | 129 | public void xmrTeleportAgent2Landmark (string agent, string landmark, LSL_Vector lookat) |
133 | { | 130 | { |
134 | // find out about agent to be teleported | 131 | // find out about agent to be teleported |
@@ -172,13 +169,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
172 | lookat, | 169 | lookat, |
173 | (uint)TeleportFlags.ViaLandmark); | 170 | (uint)TeleportFlags.ViaLandmark); |
174 | } | 171 | } |
175 | 172 | */ | |
176 | /** | 173 | /** |
177 | * @brief Allow any member of group given by config SetParcelMusicURLGroup to set music URL. | 174 | * @brief Allow any member of group given by config SetParcelMusicURLGroup to set music URL. |
178 | * Code modelled after llSetParcelMusicURL(). | 175 | * Code modelled after llSetParcelMusicURL(). |
179 | * @param newurl = new URL to set (or "" to leave it alone) | 176 | * @param newurl = new URL to set (or "" to leave it alone) |
180 | * @returns previous URL string | 177 | * @returns previous URL string |
181 | */ | 178 | */ |
179 | /* engines should not have own API | ||
182 | public string xmrSetParcelMusicURLGroup (string newurl) | 180 | public string xmrSetParcelMusicURLGroup (string newurl) |
183 | { | 181 | { |
184 | string groupname = m_ScriptEngine.Config.GetString ("SetParcelMusicURLGroup", ""); | 182 | string groupname = m_ScriptEngine.Config.GetString ("SetParcelMusicURLGroup", ""); |
@@ -200,6 +198,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
200 | if ((newurl != null) && (newurl != "")) land.SetMusicUrl (newurl); | 198 | if ((newurl != null) && (newurl != "")) land.SetMusicUrl (newurl); |
201 | return oldurl; | 199 | return oldurl; |
202 | } | 200 | } |
201 | */ | ||
203 | } | 202 | } |
204 | 203 | ||
205 | public partial class XMRInstance | 204 | public partial class XMRInstance |
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs index 8950d63..ed33108 100644 --- a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs +++ b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs | |||
@@ -27,22 +27,10 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Threading; | 29 | using System.Threading; |
30 | using System.Reflection; | ||
31 | using System.Collections; | ||
32 | using System.Collections.Generic; | ||
33 | using System.Runtime.Remoting.Lifetime; | ||
34 | using System.Security.Policy; | ||
35 | using System.IO; | 30 | using System.IO; |
36 | using System.Xml; | 31 | using System.Xml; |
37 | using System.Text; | ||
38 | using OpenMetaverse; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
41 | using OpenSim.Region.ScriptEngine.Shared; | 32 | using OpenSim.Region.ScriptEngine.Shared; |
42 | using OpenSim.Region.ScriptEngine.Shared.Api; | 33 | using OpenSim.Region.ScriptEngine.Shared.Api; |
43 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
44 | using OpenSim.Region.ScriptEngine.XMREngine; | ||
45 | using OpenSim.Region.Framework.Scenes; | ||
46 | using log4net; | 34 | using log4net; |
47 | 35 | ||
48 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; | 36 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; |
@@ -78,9 +66,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
78 | */ | 66 | */ |
79 | public XmlElement GetExecutionState(XmlDocument doc) | 67 | public XmlElement GetExecutionState(XmlDocument doc) |
80 | { | 68 | { |
81 | /* | 69 | // When we're detaching an attachment, we need to wait here. |
82 | * When we're detaching an attachment, we need to wait here. | ||
83 | */ | ||
84 | 70 | ||
85 | // Change this to a 5 second timeout. If things do mess up, | 71 | // Change this to a 5 second timeout. If things do mess up, |
86 | // we don't want to be stuck forever. | 72 | // we don't want to be stuck forever. |
@@ -92,20 +78,16 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
92 | scriptStateN.SetAttribute("Asset", m_Item.AssetID.ToString()); | 78 | scriptStateN.SetAttribute("Asset", m_Item.AssetID.ToString()); |
93 | scriptStateN.SetAttribute ("SourceHash", m_ObjCode.sourceHash); | 79 | scriptStateN.SetAttribute ("SourceHash", m_ObjCode.sourceHash); |
94 | 80 | ||
95 | /* | 81 | // Make sure we aren't executing part of the script so it stays |
96 | * Make sure we aren't executing part of the script so it stays | 82 | // stable. Setting suspendOnCheckRun tells CheckRun() to suspend |
97 | * stable. Setting suspendOnCheckRun tells CheckRun() to suspend | 83 | // and return out so RunOne() will release the lock asap. |
98 | * and return out so RunOne() will release the lock asap. | ||
99 | */ | ||
100 | suspendOnCheckRunHold = true; | 84 | suspendOnCheckRunHold = true; |
101 | lock (m_RunLock) | 85 | lock (m_RunLock) |
102 | { | 86 | { |
103 | m_RunOnePhase = "GetExecutionState enter"; | 87 | m_RunOnePhase = "GetExecutionState enter"; |
104 | CheckRunLockInvariants(true); | 88 | CheckRunLockInvariants(true); |
105 | 89 | ||
106 | /* | 90 | // Get copy of script globals and stack in relocateable form. |
107 | * Get copy of script globals and stack in relocateable form. | ||
108 | */ | ||
109 | MemoryStream snapshotStream = new MemoryStream(); | 91 | MemoryStream snapshotStream = new MemoryStream(); |
110 | MigrateOutEventHandler(snapshotStream); | 92 | MigrateOutEventHandler(snapshotStream); |
111 | Byte[] snapshotBytes = snapshotStream.ToArray(); | 93 | Byte[] snapshotBytes = snapshotStream.ToArray(); |
@@ -116,25 +98,19 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
116 | scriptStateN.AppendChild(snapshotN); | 98 | scriptStateN.AppendChild(snapshotN); |
117 | m_RunOnePhase = "GetExecutionState B"; CheckRunLockInvariants(true); | 99 | m_RunOnePhase = "GetExecutionState B"; CheckRunLockInvariants(true); |
118 | 100 | ||
119 | /* | 101 | // "Running" says whether or not we are accepting new events. |
120 | * "Running" says whether or not we are accepting new events. | ||
121 | */ | ||
122 | XmlElement runningN = doc.CreateElement("", "Running", ""); | 102 | XmlElement runningN = doc.CreateElement("", "Running", ""); |
123 | runningN.AppendChild(doc.CreateTextNode(m_Running.ToString())); | 103 | runningN.AppendChild(doc.CreateTextNode(m_Running.ToString())); |
124 | scriptStateN.AppendChild(runningN); | 104 | scriptStateN.AppendChild(runningN); |
125 | m_RunOnePhase = "GetExecutionState C"; CheckRunLockInvariants(true); | 105 | m_RunOnePhase = "GetExecutionState C"; CheckRunLockInvariants(true); |
126 | 106 | ||
127 | /* | 107 | // "DoGblInit" says whether or not default:state_entry() will init global vars. |
128 | * "DoGblInit" says whether or not default:state_entry() will init global vars. | ||
129 | */ | ||
130 | XmlElement doGblInitN = doc.CreateElement("", "DoGblInit", ""); | 108 | XmlElement doGblInitN = doc.CreateElement("", "DoGblInit", ""); |
131 | doGblInitN.AppendChild(doc.CreateTextNode(doGblInit.ToString())); | 109 | doGblInitN.AppendChild(doc.CreateTextNode(doGblInit.ToString())); |
132 | scriptStateN.AppendChild(doGblInitN); | 110 | scriptStateN.AppendChild(doGblInitN); |
133 | m_RunOnePhase = "GetExecutionState D"; CheckRunLockInvariants(true); | 111 | m_RunOnePhase = "GetExecutionState D"; CheckRunLockInvariants(true); |
134 | 112 | ||
135 | /* | 113 | // More misc data. |
136 | * More misc data. | ||
137 | */ | ||
138 | XmlNode permissionsN = doc.CreateElement("", "Permissions", ""); | 114 | XmlNode permissionsN = doc.CreateElement("", "Permissions", ""); |
139 | scriptStateN.AppendChild(permissionsN); | 115 | scriptStateN.AppendChild(permissionsN); |
140 | 116 | ||
@@ -147,10 +123,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
147 | permissionsN.Attributes.Append(maskA); | 123 | permissionsN.Attributes.Append(maskA); |
148 | m_RunOnePhase = "GetExecutionState E"; CheckRunLockInvariants(true); | 124 | m_RunOnePhase = "GetExecutionState E"; CheckRunLockInvariants(true); |
149 | 125 | ||
150 | /* | 126 | // "DetectParams" are returned by llDetected...() script functions |
151 | * "DetectParams" are returned by llDetected...() script functions | 127 | // for the currently active event, if any. |
152 | * for the currently active event, if any. | ||
153 | */ | ||
154 | if (m_DetectParams != null) | 128 | if (m_DetectParams != null) |
155 | { | 129 | { |
156 | XmlElement detParArrayN = doc.CreateElement("", "DetectArray", ""); | 130 | XmlElement detParArrayN = doc.CreateElement("", "DetectArray", ""); |
@@ -159,16 +133,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
159 | } | 133 | } |
160 | m_RunOnePhase = "GetExecutionState F"; CheckRunLockInvariants(true); | 134 | m_RunOnePhase = "GetExecutionState F"; CheckRunLockInvariants(true); |
161 | 135 | ||
162 | /* | 136 | // Save any events we have in the queue. |
163 | * Save any events we have in the queue. | 137 | // <EventQueue> |
164 | * <EventQueue> | 138 | // <Event Name="..."> |
165 | * <Event Name="..."> | 139 | // <param>...</param> ... |
166 | * <param>...</param> ... | 140 | // <DetectParams>...</DetectParams> ... |
167 | * <DetectParams>...</DetectParams> ... | 141 | // </Event> |
168 | * </Event> | 142 | // ... |
169 | * ... | 143 | // </EventQueue> |
170 | * </EventQueue> | ||
171 | */ | ||
172 | XmlElement queuedEventsN = doc.CreateElement("", "EventQueue", ""); | 144 | XmlElement queuedEventsN = doc.CreateElement("", "EventQueue", ""); |
173 | lock (m_QueueLock) | 145 | lock (m_QueueLock) |
174 | { | 146 | { |
@@ -184,31 +156,24 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
184 | scriptStateN.AppendChild(queuedEventsN); | 156 | scriptStateN.AppendChild(queuedEventsN); |
185 | m_RunOnePhase = "GetExecutionState G"; CheckRunLockInvariants(true); | 157 | m_RunOnePhase = "GetExecutionState G"; CheckRunLockInvariants(true); |
186 | 158 | ||
187 | /* | 159 | // "Plugins" indicate enabled timers and listens, etc. |
188 | * "Plugins" indicate enabled timers and listens, etc. | ||
189 | */ | ||
190 | Object[] pluginData = | 160 | Object[] pluginData = |
191 | AsyncCommandManager.GetSerializationData(m_Engine, | 161 | AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID); |
192 | m_ItemID); | ||
193 | 162 | ||
194 | XmlNode plugins = doc.CreateElement("", "Plugins", ""); | 163 | XmlNode plugins = doc.CreateElement("", "Plugins", ""); |
195 | AppendXMLObjectArray(doc, plugins, pluginData, "plugin"); | 164 | AppendXMLObjectArray(doc, plugins, pluginData, "plugin"); |
196 | scriptStateN.AppendChild(plugins); | 165 | scriptStateN.AppendChild(plugins); |
197 | m_RunOnePhase = "GetExecutionState H"; CheckRunLockInvariants(true); | 166 | m_RunOnePhase = "GetExecutionState H"; CheckRunLockInvariants(true); |
198 | 167 | ||
199 | /* | 168 | // Let script run again. |
200 | * Let script run again. | ||
201 | */ | ||
202 | suspendOnCheckRunHold = false; | 169 | suspendOnCheckRunHold = false; |
203 | 170 | ||
204 | m_RunOnePhase = "GetExecutionState leave"; | 171 | m_RunOnePhase = "GetExecutionState leave"; |
205 | CheckRunLockInvariants(true); | 172 | CheckRunLockInvariants(true); |
206 | } | 173 | } |
207 | 174 | ||
208 | /* | 175 | // scriptStateN represents the contents of the .state file so |
209 | * scriptStateN represents the contents of the .state file so | 176 | // write the .state file while we are here. |
210 | * write the .state file while we are here. | ||
211 | */ | ||
212 | FileStream fs = File.Create(m_StateFileName); | 177 | FileStream fs = File.Create(m_StateFileName); |
213 | StreamWriter sw = new StreamWriter(fs); | 178 | StreamWriter sw = new StreamWriter(fs); |
214 | sw.Write(scriptStateN.OuterXml); | 179 | sw.Write(scriptStateN.OuterXml); |
@@ -233,32 +198,33 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
233 | // do all the work in the MigrateOutEventHandlerThread() method below | 198 | // do all the work in the MigrateOutEventHandlerThread() method below |
234 | moehstream = stream; | 199 | moehstream = stream; |
235 | 200 | ||
236 | XMRScriptThread cst = XMRScriptThread.CurrentScriptThread (); | 201 | XMRScriptThread cst = m_Engine.CurrentScriptThread (); |
237 | if (cst != null) { | 202 | if (cst != null) |
203 | { | ||
238 | 204 | ||
239 | // we might be getting called inside some LSL Api function | 205 | // we might be getting called inside some LSL Api function |
240 | // so we are already in script thread and thus must do | 206 | // so we are already in script thread and thus must do |
241 | // migration directly | 207 | // migration directly |
242 | MigrateOutEventHandlerThread (); | 208 | MigrateOutEventHandlerThread (); |
243 | } else { | 209 | } |
244 | 210 | else | |
211 | { | ||
245 | // some other thread, do migration via a script thread | 212 | // some other thread, do migration via a script thread |
246 | lock (XMRScriptThread.m_WakeUpLock) { | 213 | m_Engine.QueueToTrunk(this.MigrateOutEventHandlerThread); |
247 | m_Engine.m_ThunkQueue.Enqueue (this.MigrateOutEventHandlerThread); | ||
248 | } | ||
249 | XMRScriptThread.WakeUpOne (); | ||
250 | 214 | ||
251 | // wait for it to complete | 215 | // wait for it to complete |
252 | lock (moehdone) { | 216 | lock (moehdone) |
253 | while (moehstream != null) { | 217 | { |
218 | while (moehstream != null) | ||
254 | Monitor.Wait (moehdone); | 219 | Monitor.Wait (moehdone); |
255 | } | ||
256 | } | 220 | } |
257 | } | 221 | } |
258 | 222 | ||
259 | // maybe it threw up | 223 | // maybe it threw up |
260 | if (moehexcep != null) throw moehexcep; | 224 | if (moehexcep != null) |
225 | throw moehexcep; | ||
261 | } | 226 | } |
227 | |||
262 | private Exception moehexcep; | 228 | private Exception moehexcep; |
263 | private object moehdone = new object (); | 229 | private object moehdone = new object (); |
264 | private Stream moehstream; | 230 | private Stream moehstream; |
@@ -266,64 +232,65 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
266 | { | 232 | { |
267 | Exception except; | 233 | Exception except; |
268 | 234 | ||
269 | try { | 235 | try |
270 | 236 | { | |
271 | /* | 237 | // Resume the microthread and it will throw a StackCaptureException() |
272 | * Resume the microthread and it will throw a StackCaptureException() | 238 | // with the stack frames saved to this.stackFrames. |
273 | * with the stack frames saved to this.stackFrames. | 239 | // Then write the saved stack frames to the output stream. |
274 | * Then write the saved stack frames to the output stream. | 240 | // |
275 | * | 241 | // There is a stack only if the event code is not None. |
276 | * There is a stack only if the event code is not None. | 242 | if (this.eventCode != ScriptEventCode.None) |
277 | */ | 243 | { |
278 | if (this.eventCode != ScriptEventCode.None) { | ||
279 | |||
280 | // tell microthread to continue | 244 | // tell microthread to continue |
281 | // it should see captureStackFrames and throw StackCaptureException() | 245 | // it should see captureStackFrames and throw StackCaptureException() |
282 | // ...generating XMRStackFrames as it unwinds | 246 | // ...generating XMRStackFrames as it unwinds |
283 | this.captureStackFrames = true; | 247 | this.captureStackFrames = true; |
248 | // this.suspendOnCheckRunTemp = true; | ||
284 | except = this.microthread.ResumeEx (); | 249 | except = this.microthread.ResumeEx (); |
285 | this.captureStackFrames = false; | 250 | this.captureStackFrames = false; |
286 | if (except == null) { | 251 | |
252 | if (except == null) | ||
287 | throw new Exception ("stack save did not complete"); | 253 | throw new Exception ("stack save did not complete"); |
288 | } | 254 | |
289 | if (!(except is StackCaptureException)) { | 255 | if (!(except is StackCaptureException)) |
290 | throw except; | 256 | throw except; |
291 | } | ||
292 | } | 257 | } |
293 | 258 | ||
294 | /* | 259 | // Write script state out, frames and all, to the stream. |
295 | * Write script state out, frames and all, to the stream. | 260 | // Does not change script state. |
296 | * Does not change script state. | 261 | |
297 | */ | ||
298 | moehstream.WriteByte (migrationVersion); | 262 | moehstream.WriteByte (migrationVersion); |
299 | moehstream.WriteByte ((byte)16); | 263 | moehstream.WriteByte ((byte)16); |
300 | this.MigrateOut (new BinaryWriter (moehstream)); | 264 | this.MigrateOut (new BinaryWriter (moehstream)); |
301 | 265 | ||
302 | /* | 266 | // Now restore script stack. |
303 | * Now restore script stack. | 267 | // Microthread will suspend inside CheckRun() when restore is complete. |
304 | * Microthread will suspend inside CheckRun() when restore is complete. | 268 | if (this.eventCode != ScriptEventCode.None) |
305 | */ | 269 | { |
306 | if (this.eventCode != ScriptEventCode.None) { | ||
307 | this.stackFramesRestored = false; | 270 | this.stackFramesRestored = false; |
308 | except = this.microthread.StartEx (); | 271 | except = this.microthread.StartEx (); |
309 | if (except != null) { | 272 | |
273 | if (except != null) | ||
310 | throw except; | 274 | throw except; |
311 | } | 275 | |
312 | if (!this.stackFramesRestored) { | 276 | if (!this.stackFramesRestored) |
313 | throw new Exception ("restore after save did not complete"); | 277 | throw new Exception ("restore after save did not complete"); |
314 | } | 278 | |
315 | } | 279 | } |
316 | } catch (Exception e) { | 280 | } |
281 | catch (Exception e) | ||
282 | { | ||
317 | moehexcep = e; | 283 | moehexcep = e; |
318 | } finally { | 284 | } |
319 | 285 | finally | |
286 | { | ||
320 | // make sure CheckRunLockInvariants() won't puque | 287 | // make sure CheckRunLockInvariants() won't puque |
321 | if (this.microthread.Active () == 0) { | 288 | if (this.microthread.Active () == 0) |
322 | this.eventCode = ScriptEventCode.None; | 289 | this.eventCode = ScriptEventCode.None; |
323 | } | ||
324 | 290 | ||
325 | // wake the MigrateOutEventHandler() method above | 291 | // wake the MigrateOutEventHandler() method above |
326 | lock (moehdone) { | 292 | lock (moehdone) |
293 | { | ||
327 | moehstream = null; | 294 | moehstream = null; |
328 | Monitor.Pulse (moehdone); | 295 | Monitor.Pulse (moehdone); |
329 | } | 296 | } |
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCtor.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCtor.cs index 1cf1ad1..7ae8c47 100644 --- a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCtor.cs +++ b/OpenSim/Region/ScriptEngine/XMREngine/XMRInstCtor.cs | |||
@@ -695,7 +695,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
695 | // do all the work in the MigrateInEventHandlerThread() method below | 695 | // do all the work in the MigrateInEventHandlerThread() method below |
696 | miehstream = stream; | 696 | miehstream = stream; |
697 | 697 | ||
698 | XMRScriptThread cst = XMRScriptThread.CurrentScriptThread (); | 698 | XMRScriptThread cst = m_Engine.CurrentScriptThread (); |
699 | if (cst != null) | 699 | if (cst != null) |
700 | { | 700 | { |
701 | // in case we are getting called inside some LSL Api function | 701 | // in case we are getting called inside some LSL Api function |
@@ -704,11 +704,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
704 | else | 704 | else |
705 | { | 705 | { |
706 | // some other thread, do migration via a script thread | 706 | // some other thread, do migration via a script thread |
707 | lock (XMRScriptThread.m_WakeUpLock) | 707 | m_Engine.QueueToTrunk(this.MigrateInEventHandlerThread); |
708 | { | ||
709 | m_Engine.m_ThunkQueue.Enqueue (this.MigrateInEventHandlerThread); | ||
710 | } | ||
711 | XMRScriptThread.WakeUpOne (); | ||
712 | 708 | ||
713 | // wait for it to complete | 709 | // wait for it to complete |
714 | lock (miehdone) | 710 | lock (miehdone) |
@@ -777,79 +773,5 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
777 | } | 773 | } |
778 | } | 774 | } |
779 | } | 775 | } |
780 | |||
781 | /** | ||
782 | * See if permitted by configuration file. | ||
783 | * See OSSL_Api.CheckThreatLevelTest(). | ||
784 | */ | ||
785 | public string CheckFetchbinaryAllowed () | ||
786 | { | ||
787 | string ownerPerm = m_Engine.Config.GetString ("Allow_fetchbinary", ""); | ||
788 | UUID ownerID = m_Item.OwnerID; | ||
789 | string[] ids = ownerPerm.Split (new char[] { ',' }); | ||
790 | foreach (string id in ids) | ||
791 | { | ||
792 | string curuc = id.Trim().ToUpperInvariant(); | ||
793 | |||
794 | switch (curuc) | ||
795 | { | ||
796 | case "ESTATE_MANAGER": | ||
797 | if (m_Engine.m_Scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner (ownerID) && | ||
798 | (m_Engine.m_Scene.RegionInfo.EstateSettings.EstateOwner != ownerID)) | ||
799 | return null; | ||
800 | |||
801 | break; | ||
802 | |||
803 | case "ESTATE_OWNER": | ||
804 | if (m_Engine.m_Scene.RegionInfo.EstateSettings.EstateOwner == ownerID) | ||
805 | return null; | ||
806 | |||
807 | break; | ||
808 | |||
809 | case "PARCEL_GROUP_MEMBER": | ||
810 | ILandObject land = m_Engine.m_Scene.LandChannel.GetLandObject (m_Part.AbsolutePosition); | ||
811 | if (land.LandData.GroupID == m_Item.GroupID && land.LandData.GroupID != UUID.Zero) | ||
812 | return null; | ||
813 | |||
814 | break; | ||
815 | |||
816 | case "PARCEL_OWNER": | ||
817 | ILandObject Oland = m_Engine.m_Scene.LandChannel.GetLandObject (m_Part.AbsolutePosition); | ||
818 | if (Oland.LandData.OwnerID == ownerID) | ||
819 | return null; | ||
820 | |||
821 | break; | ||
822 | |||
823 | case "TRUE": | ||
824 | return null; | ||
825 | |||
826 | default: | ||
827 | UUID uuid; | ||
828 | if (UUID.TryParse (curuc, out uuid)) | ||
829 | if (uuid == ownerID) return null; | ||
830 | |||
831 | break; | ||
832 | } | ||
833 | } | ||
834 | |||
835 | string creatorPerm = m_Engine.Config.GetString ("Creators_fetchbinary", ""); | ||
836 | UUID creatorID = m_Item.CreatorID; | ||
837 | ids = creatorPerm.Split (new char[] { ',' }); | ||
838 | foreach (string id in ids) | ||
839 | { | ||
840 | string current = id.Trim (); | ||
841 | UUID uuid; | ||
842 | if (UUID.TryParse (current, out uuid)) | ||
843 | { | ||
844 | if (uuid != UUID.Zero) | ||
845 | { | ||
846 | if (creatorID == uuid) | ||
847 | return null; | ||
848 | } | ||
849 | } | ||
850 | } | ||
851 | |||
852 | return "fetchbinary not enabled for owner " + ownerID + " creator " + creatorID; | ||
853 | } | ||
854 | } | 776 | } |
855 | } | 777 | } |
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRScriptThread.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMRScriptThread.cs index 6470477..7103556 100644 --- a/OpenSim/Region/ScriptEngine/XMREngine/XMRScriptThread.cs +++ b/OpenSim/Region/ScriptEngine/XMREngine/XMRScriptThread.cs | |||
@@ -32,7 +32,6 @@ using System.Threading; | |||
32 | 32 | ||
33 | namespace OpenSim.Region.ScriptEngine.XMREngine | 33 | namespace OpenSim.Region.ScriptEngine.XMREngine |
34 | { | 34 | { |
35 | |||
36 | /** | 35 | /** |
37 | * @brief There are NUMSCRIPTHREADWKRS of these. | 36 | * @brief There are NUMSCRIPTHREADWKRS of these. |
38 | * Each sits in a loop checking the Start and Yield queues for | 37 | * Each sits in a loop checking the Start and Yield queues for |
@@ -40,35 +39,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
40 | */ | 39 | */ |
41 | public class XMRScriptThread | 40 | public class XMRScriptThread |
42 | { | 41 | { |
43 | private static int m_WakeUpOne = 0; | 42 | public bool m_WakeUpThis = false; |
44 | public static object m_WakeUpLock = new object(); | ||
45 | private static Dictionary<Thread,XMRScriptThread> m_AllThreads = new Dictionary<Thread,XMRScriptThread> (); | ||
46 | |||
47 | /** | ||
48 | * @brief Something was just added to the Start or Yield queue so | ||
49 | * wake one of the XMRScriptThread instances to run it. | ||
50 | */ | ||
51 | public static void WakeUpOne() | ||
52 | { | ||
53 | lock (m_WakeUpLock) | ||
54 | { | ||
55 | m_WakeUpOne ++; | ||
56 | Monitor.Pulse (m_WakeUpLock); | ||
57 | } | ||
58 | } | ||
59 | |||
60 | public static XMRScriptThread CurrentScriptThread () | ||
61 | { | ||
62 | XMRScriptThread st; | ||
63 | lock (m_AllThreads) { | ||
64 | m_AllThreads.TryGetValue (Thread.CurrentThread, out st); | ||
65 | } | ||
66 | return st; | ||
67 | } | ||
68 | |||
69 | private bool m_Exiting = false; | ||
70 | private bool m_SuspendScriptThreadFlag = false; | ||
71 | private bool m_WakeUpThis = false; | ||
72 | public DateTime m_LastRanAt = DateTime.MinValue; | 43 | public DateTime m_LastRanAt = DateTime.MinValue; |
73 | public int m_ScriptThreadTID = 0; | 44 | public int m_ScriptThreadTID = 0; |
74 | public long m_ScriptExecTime = 0; | 45 | public long m_ScriptExecTime = 0; |
@@ -80,164 +51,43 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
80 | { | 51 | { |
81 | engine = eng; | 52 | engine = eng; |
82 | if(i < 0) | 53 | if(i < 0) |
83 | thd = XMREngine.StartMyThread (RunScriptThread, "xmrengine script", ThreadPriority.Normal); | 54 | thd = XMREngine.StartMyThread(RunScriptThread, "xmrengine script", ThreadPriority.Normal); |
84 | else | 55 | else |
85 | thd = XMREngine.StartMyThread (RunScriptThread, "xmrengineExec" + i.ToString(), ThreadPriority.Normal); | 56 | thd = XMREngine.StartMyThread(RunScriptThread, "xmrengineExec" + i.ToString(), ThreadPriority.Normal); |
86 | lock (m_AllThreads) | 57 | engine.AddThread(thd, this); |
87 | m_AllThreads.Add (thd, this); | 58 | m_ScriptThreadTID = thd.ManagedThreadId; |
88 | } | ||
89 | |||
90 | public void SuspendThread() | ||
91 | { | ||
92 | m_SuspendScriptThreadFlag = true; | ||
93 | WakeUpScriptThread(); | ||
94 | } | ||
95 | |||
96 | public void ResumeThread() | ||
97 | { | ||
98 | m_SuspendScriptThreadFlag = false; | ||
99 | WakeUpScriptThread(); | ||
100 | } | 59 | } |
101 | 60 | ||
102 | public void Terminate() | 61 | public void Terminate() |
103 | { | 62 | { |
104 | m_Exiting = true; | 63 | m_WakeUpThis = true; |
105 | WakeUpScriptThread(); | ||
106 | if(!thd.Join(250)) | 64 | if(!thd.Join(250)) |
107 | thd.Abort(); | 65 | thd.Abort(); |
108 | lock (m_AllThreads) | ||
109 | m_AllThreads.Remove (thd); | ||
110 | 66 | ||
111 | thd = null; | 67 | engine.RemoveThread(thd); |
112 | } | ||
113 | 68 | ||
114 | public void TimeSlice() | 69 | thd = null; |
115 | { | ||
116 | XMRInstance instance = m_RunInstance; | ||
117 | if (instance != null) | ||
118 | instance.suspendOnCheckRunTemp = true; | ||
119 | } | 70 | } |
120 | 71 | ||
121 | /** | 72 | /** |
122 | * @brief Wake up this XMRScriptThread instance. | 73 | * @brief Wake up this XMRScriptThread instance. |
123 | */ | 74 | */ |
124 | private void WakeUpScriptThread() | 75 | public void WakeUpScriptThread() |
125 | { | 76 | { |
126 | lock (m_WakeUpLock) | ||
127 | { | ||
128 | m_WakeUpThis = true; | 77 | m_WakeUpThis = true; |
129 | Monitor.PulseAll (m_WakeUpLock); | ||
130 | } | ||
131 | } | 78 | } |
132 | 79 | ||
133 | /** | 80 | /** |
134 | * @brief Thread that runs the scripts. | 81 | * @brief A script instance was just removed from the Start or Yield Queue. |
82 | * So run it for a little bit then stick in whatever queue it should go in. | ||
135 | */ | 83 | */ |
84 | |||
136 | private void RunScriptThread() | 85 | private void RunScriptThread() |
137 | { | 86 | { |
138 | XMRInstance inst; | 87 | engine.RunScriptThread(this); |
139 | m_ScriptThreadTID = System.Threading.Thread.CurrentThread.ManagedThreadId; | ||
140 | |||
141 | while (!m_Exiting) | ||
142 | { | ||
143 | XMREngine.UpdateMyThread (); | ||
144 | |||
145 | /* | ||
146 | * Handle 'xmr resume/suspend' commands. | ||
147 | */ | ||
148 | if (m_SuspendScriptThreadFlag) | ||
149 | { | ||
150 | lock (m_WakeUpLock) { | ||
151 | while (m_SuspendScriptThreadFlag && | ||
152 | !m_Exiting && | ||
153 | (engine.m_ThunkQueue.Count == 0)) | ||
154 | { | ||
155 | Monitor.Wait (m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2); | ||
156 | XMREngine.UpdateMyThread (); | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * Maybe there are some scripts waiting to be migrated in or out. | ||
163 | */ | ||
164 | ThreadStart thunk = null; | ||
165 | lock (m_WakeUpLock) | ||
166 | { | ||
167 | if (engine.m_ThunkQueue.Count > 0) | ||
168 | thunk = engine.m_ThunkQueue.Dequeue (); | ||
169 | } | ||
170 | if (thunk != null) | ||
171 | { | ||
172 | inst = (XMRInstance)thunk.Target; | ||
173 | thunk (); | ||
174 | continue; | ||
175 | } | ||
176 | |||
177 | if (engine.m_StartProcessing) | ||
178 | { | ||
179 | // If event just queued to any idle scripts | ||
180 | // start them right away. But only start so | ||
181 | // many so we can make some progress on yield | ||
182 | // queue. | ||
183 | |||
184 | int numStarts; | ||
185 | for (numStarts = 5; -- numStarts >= 0;) | ||
186 | { | ||
187 | lock (engine.m_StartQueue) | ||
188 | { | ||
189 | inst = engine.m_StartQueue.RemoveHead(); | ||
190 | } | ||
191 | if (inst == null) break; | ||
192 | if (inst.m_IState != XMRInstState.ONSTARTQ) throw new Exception("bad state"); | ||
193 | RunInstance (inst); | ||
194 | } | ||
195 | |||
196 | // If there is something to run, run it | ||
197 | // then rescan from the beginning in case | ||
198 | // a lot of things have changed meanwhile. | ||
199 | // | ||
200 | // These are considered lower priority than | ||
201 | // m_StartQueue as they have been taking at | ||
202 | // least one quantum of CPU time and event | ||
203 | // handlers are supposed to be quick. | ||
204 | |||
205 | lock (engine.m_YieldQueue) | ||
206 | { | ||
207 | inst = engine.m_YieldQueue.RemoveHead(); | ||
208 | } | ||
209 | if (inst != null) | ||
210 | { | ||
211 | if (inst.m_IState != XMRInstState.ONYIELDQ) throw new Exception("bad state"); | ||
212 | RunInstance(inst); | ||
213 | numStarts = -1; | ||
214 | } | ||
215 | |||
216 | // If we left something dangling in the m_StartQueue or m_YieldQueue, go back to check it. | ||
217 | if (numStarts < 0) | ||
218 | continue; | ||
219 | } | ||
220 | |||
221 | // Nothing to do, sleep. | ||
222 | |||
223 | lock (m_WakeUpLock) | ||
224 | { | ||
225 | if (!m_WakeUpThis && (m_WakeUpOne <= 0) && !m_Exiting) | ||
226 | Monitor.Wait(m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2); | ||
227 | |||
228 | m_WakeUpThis = false; | ||
229 | if ((m_WakeUpOne > 0) && (-- m_WakeUpOne > 0)) | ||
230 | Monitor.Pulse (m_WakeUpLock); | ||
231 | } | ||
232 | } | ||
233 | XMREngine.MyThreadExiting (); | ||
234 | } | 88 | } |
235 | 89 | ||
236 | /** | 90 | public void RunInstance (XMRInstance inst) |
237 | * @brief A script instance was just removed from the Start or Yield Queue. | ||
238 | * So run it for a little bit then stick in whatever queue it should go in. | ||
239 | */ | ||
240 | private void RunInstance (XMRInstance inst) | ||
241 | { | 91 | { |
242 | m_LastRanAt = DateTime.UtcNow; | 92 | m_LastRanAt = DateTime.UtcNow; |
243 | m_ScriptExecTime -= (long)(m_LastRanAt - DateTime.MinValue).TotalMilliseconds; | 93 | m_ScriptExecTime -= (long)(m_LastRanAt - DateTime.MinValue).TotalMilliseconds; |
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRScriptUThread.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMRScriptUThread.cs index 74bba4f..ca2806e 100644 --- a/OpenSim/Region/ScriptEngine/XMREngine/XMRScriptUThread.cs +++ b/OpenSim/Region/ScriptEngine/XMREngine/XMRScriptUThread.cs | |||
@@ -57,21 +57,28 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
57 | public Exception StartEx () | 57 | public Exception StartEx () |
58 | { | 58 | { |
59 | // We should only be called when no event handler running. | 59 | // We should only be called when no event handler running. |
60 | if (active != 0) throw new Exception ("active=" + active); | 60 | if (active != 0) |
61 | throw new Exception ("active=" + active); | ||
61 | 62 | ||
62 | // Start script event handler from very beginning. | 63 | // Start script event handler from very beginning. |
63 | active = 1; | 64 | active = 1; |
64 | Exception except = null; | 65 | Exception except = null; |
65 | instance.callMode = XMRInstance.CallMode_NORMAL; | 66 | instance.callMode = XMRInstance.CallMode_NORMAL; |
66 | try { | 67 | try |
68 | { | ||
67 | instance.CallSEH (); // run script event handler | 69 | instance.CallSEH (); // run script event handler |
68 | active = 0; | 70 | active = 0; |
69 | } catch (StackHibernateException) { | 71 | } |
70 | if (instance.callMode != XMRInstance.CallMode_SAVE) { | 72 | catch (StackHibernateException) |
73 | { | ||
74 | if (instance.callMode != XMRInstance.CallMode_SAVE) | ||
75 | { | ||
71 | throw new Exception ("callMode=" + instance.callMode); | 76 | throw new Exception ("callMode=" + instance.callMode); |
72 | } | 77 | } |
73 | active = -1; // it is hibernating, can be resumed | 78 | active = -1; // it is hibernating, can be resumed |
74 | } catch (Exception e) { | 79 | } |
80 | catch (Exception e) | ||
81 | { | ||
75 | active = 0; | 82 | active = 0; |
76 | except = e; // threw exception, save for Start()/Resume() | 83 | except = e; // threw exception, save for Start()/Resume() |
77 | } | 84 | } |
@@ -88,21 +95,28 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
88 | public Exception ResumeEx () | 95 | public Exception ResumeEx () |
89 | { | 96 | { |
90 | // We should only be called when script is hibernating. | 97 | // We should only be called when script is hibernating. |
91 | if (active >= 0) throw new Exception ("active=" + active); | 98 | if (active >= 0) |
99 | throw new Exception ("active=" + active); | ||
92 | 100 | ||
93 | // Resume script from captured stack. | 101 | // Resume script from captured stack. |
94 | instance.callMode = XMRInstance.CallMode_RESTORE; | 102 | instance.callMode = XMRInstance.CallMode_RESTORE; |
95 | instance.suspendOnCheckRunTemp = true; | 103 | instance.suspendOnCheckRunTemp = true; |
96 | Exception except = null; | 104 | Exception except = null; |
97 | try { | 105 | try |
106 | { | ||
98 | instance.CallSEH (); // run script event handler | 107 | instance.CallSEH (); // run script event handler |
99 | active = 0; | 108 | active = 0; |
100 | } catch (StackHibernateException) { | 109 | } |
101 | if (instance.callMode != XMRInstance.CallMode_SAVE) { | 110 | catch (StackHibernateException) |
111 | { | ||
112 | if (instance.callMode != XMRInstance.CallMode_SAVE) | ||
113 | { | ||
102 | throw new Exception ("callMode=" + instance.callMode); | 114 | throw new Exception ("callMode=" + instance.callMode); |
103 | } | 115 | } |
104 | active = -1; | 116 | active = -1; |
105 | } catch (Exception e) { | 117 | } |
118 | catch (Exception e) | ||
119 | { | ||
106 | active = 0; | 120 | active = 0; |
107 | except = e; // threw exception, save for Start()/Resume() | 121 | except = e; // threw exception, save for Start()/Resume() |
108 | } | 122 | } |