aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/MMRScriptInlines.cs56
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/XMREngine.cs177
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/XMRInstAbstract.cs50
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/XMRInstBackend.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/XMRInstCapture.cs175
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/XMRInstCtor.cs82
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/XMRScriptThread.cs180
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/XMRScriptUThread.cs34
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;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
34using OpenSim.Region.ScriptEngine.Shared.Api; 34using OpenSim.Region.ScriptEngine.Shared.Api;
35using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
36using OpenSim.Region.ScriptEngine.XMREngine;
37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Region.Framework.Scenes.Scripting;
39using OpenSim.Region.Framework.Interfaces;
40using log4net; 35using log4net;
41 36
42using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 37using 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
28using System; 28using System;
29using System.Threading; 29using System.Threading;
30using System.Reflection;
31using System.Collections;
32using System.Collections.Generic;
33using System.Runtime.Remoting.Lifetime;
34using System.Security.Policy;
35using System.IO; 30using System.IO;
36using System.Xml; 31using System.Xml;
37using System.Text;
38using OpenMetaverse;
39using OpenSim.Framework;
40using OpenSim.Region.ScriptEngine.Interfaces;
41using OpenSim.Region.ScriptEngine.Shared; 32using OpenSim.Region.ScriptEngine.Shared;
42using OpenSim.Region.ScriptEngine.Shared.Api; 33using OpenSim.Region.ScriptEngine.Shared.Api;
43using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
44using OpenSim.Region.ScriptEngine.XMREngine;
45using OpenSim.Region.Framework.Scenes;
46using log4net; 34using log4net;
47 35
48using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 36using 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
33namespace OpenSim.Region.ScriptEngine.XMREngine 33namespace 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 }