try to fix xmr on multiregions per instance. Ugly spargetti ...; remove fixes for 2 llparcel functions that should not be needed; remove xmr own API, it has no business having one.
parent
cddb848c13
commit
01ceb4d17e
|
@ -589,11 +589,11 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
* @brief Generate code for the usual ll...() functions.
|
* @brief Generate code for the usual ll...() functions.
|
||||||
*/
|
*/
|
||||||
public class TokenDeclInline_BEApi : TokenDeclInline {
|
public class TokenDeclInline_BEApi : TokenDeclInline {
|
||||||
private static readonly MethodInfo fixLLParcelMediaQuery = ScriptCodeGen.GetStaticMethod
|
// private static readonly MethodInfo fixLLParcelMediaQuery = ScriptCodeGen.GetStaticMethod
|
||||||
(typeof (XMRInstAbstract), "FixLLParcelMediaQuery", new Type[] { typeof (LSL_List) });
|
// (typeof (XMRInstAbstract), "FixLLParcelMediaQuery", new Type[] { typeof (LSL_List) });
|
||||||
|
|
||||||
private static readonly MethodInfo fixLLParcelMediaCommandList = ScriptCodeGen.GetStaticMethod
|
// private static readonly MethodInfo fixLLParcelMediaCommandList = ScriptCodeGen.GetStaticMethod
|
||||||
(typeof (XMRInstAbstract), "FixLLParcelMediaCommandList", new Type[] { typeof (LSL_List) });
|
// (typeof (XMRInstAbstract), "FixLLParcelMediaCommandList", new Type[] { typeof (LSL_List) });
|
||||||
|
|
||||||
public bool doCheckRun;
|
public bool doCheckRun;
|
||||||
private FieldInfo apiContextField;
|
private FieldInfo apiContextField;
|
||||||
|
@ -626,39 +626,41 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
*/
|
*/
|
||||||
public override void CodeGen (ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args)
|
public override void CodeGen (ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args)
|
||||||
{
|
{
|
||||||
if (isTaggedCallsCheckRun) { // see if 'xmr' method that calls CheckRun() internally
|
if (isTaggedCallsCheckRun)
|
||||||
new ScriptCodeGen.CallLabel (scg, errorAt); // if so, put a call label immediately before it
|
{ // see if 'xmr' method that calls CheckRun() internally
|
||||||
// .. so restoring the frame will jump immediately to the
|
new ScriptCodeGen.CallLabel (scg, errorAt); // if so, put a call label immediately before it
|
||||||
// .. call without re-executing any code before this
|
// .. so restoring the frame will jump immediately to the
|
||||||
|
// .. call without re-executing any code before this
|
||||||
}
|
}
|
||||||
if (!methInfo.IsStatic) {
|
if (!methInfo.IsStatic)
|
||||||
|
{
|
||||||
scg.PushXMRInst (); // XMRInstanceSuperType pointer
|
scg.PushXMRInst (); // XMRInstanceSuperType pointer
|
||||||
if (apiContextField != null) {
|
if (apiContextField != null) // 'this' pointer for API function
|
||||||
scg.ilGen.Emit (errorAt, OpCodes.Ldfld, apiContextField);
|
scg.ilGen.Emit (errorAt, OpCodes.Ldfld, apiContextField);
|
||||||
// 'this' pointer for API function
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < args.Length; i ++) { // push arguments, boxing/unboxing as needed
|
for (int i = 0; i < args.Length; i ++) // push arguments, boxing/unboxing as needed
|
||||||
args[i].PushVal (scg, errorAt, argDecl.types[i]);
|
args[i].PushVal (scg, errorAt, argDecl.types[i]);
|
||||||
}
|
|
||||||
if (methInfo.Name == "llParcelMediaQuery") {
|
// this should not be needed
|
||||||
scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaQuery);
|
// if (methInfo.Name == "llParcelMediaQuery") {
|
||||||
}
|
// scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaQuery);
|
||||||
if (methInfo.Name == "llParcelMediaCommandList") {
|
// }
|
||||||
scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaCommandList);
|
// this should not be needed
|
||||||
}
|
// if (methInfo.Name == "llParcelMediaCommandList") {
|
||||||
if (methInfo.IsVirtual) { // call API function
|
// scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaCommandList);
|
||||||
|
// }
|
||||||
|
if (methInfo.IsVirtual) // call API function
|
||||||
scg.ilGen.Emit (errorAt, OpCodes.Callvirt, methInfo);
|
scg.ilGen.Emit (errorAt, OpCodes.Callvirt, methInfo);
|
||||||
} else {
|
else
|
||||||
scg.ilGen.Emit (errorAt, OpCodes.Call, methInfo);
|
scg.ilGen.Emit (errorAt, OpCodes.Call, methInfo);
|
||||||
}
|
|
||||||
result.Pop (scg, errorAt, retType); // pop result, boxing/unboxing as needed
|
result.Pop (scg, errorAt, retType); // pop result, boxing/unboxing as needed
|
||||||
if (isTaggedCallsCheckRun) {
|
if (isTaggedCallsCheckRun)
|
||||||
scg.openCallLabel = null;
|
scg.openCallLabel = null;
|
||||||
}
|
|
||||||
if (doCheckRun) {
|
if (doCheckRun)
|
||||||
scg.EmitCallCheckRun (errorAt, false); // maybe call CheckRun()
|
scg.EmitCallCheckRun (errorAt, false); // maybe call CheckRun()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,18 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
new Dictionary<string,FieldInfo> ();
|
new Dictionary<string,FieldInfo> ();
|
||||||
private int m_StackSize;
|
private int m_StackSize;
|
||||||
private int m_HeapSize;
|
private int m_HeapSize;
|
||||||
|
|
||||||
private XMRScriptThread[] m_ScriptThreads;
|
private XMRScriptThread[] m_ScriptThreads;
|
||||||
|
private int m_WakeUpOne = 0;
|
||||||
|
public object m_WakeUpLock = new object();
|
||||||
|
private Dictionary<Thread,XMRScriptThread> m_AllThreads = new Dictionary<Thread,XMRScriptThread> ();
|
||||||
|
|
||||||
|
private bool m_SuspendScriptThreadFlag = false;
|
||||||
|
/**
|
||||||
|
* @brief Something was just added to the Start or Yield queue so
|
||||||
|
* wake one of the XMRScriptThread instances to run it.
|
||||||
|
*/
|
||||||
|
|
||||||
private Thread m_SleepThread = null;
|
private Thread m_SleepThread = null;
|
||||||
private bool m_Exiting = false;
|
private bool m_Exiting = false;
|
||||||
|
|
||||||
|
@ -165,6 +176,36 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
get { return scriptReferencedAssemblies; }
|
get { return scriptReferencedAssemblies; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void WakeUpOne()
|
||||||
|
{
|
||||||
|
lock (m_WakeUpLock)
|
||||||
|
{
|
||||||
|
m_WakeUpOne++;
|
||||||
|
Monitor.Pulse(m_WakeUpLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddThread(Thread thd, XMRScriptThread xthd)
|
||||||
|
{
|
||||||
|
lock(m_AllThreads)
|
||||||
|
m_AllThreads.Add(thd, xthd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveThread(Thread thd)
|
||||||
|
{
|
||||||
|
lock(m_AllThreads)
|
||||||
|
m_AllThreads.Remove(thd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XMRScriptThread CurrentScriptThread ()
|
||||||
|
{
|
||||||
|
XMRScriptThread st;
|
||||||
|
lock (m_AllThreads)
|
||||||
|
m_AllThreads.TryGetValue (Thread.CurrentThread, out st);
|
||||||
|
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
public void Initialise(IConfigSource config)
|
public void Initialise(IConfigSource config)
|
||||||
{
|
{
|
||||||
TraceCalls("[XMREngine]: Initialize entry");
|
TraceCalls("[XMREngine]: Initialize entry");
|
||||||
|
@ -235,7 +276,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < numThreadScriptWorkers; i ++)
|
for (int i = 0; i < numThreadScriptWorkers; i ++)
|
||||||
m_ScriptThreads[i] = new XMRScriptThread(this, i);
|
{
|
||||||
|
m_ScriptThreads[i] = new XMRScriptThread(this, i);;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
m_SleepThread = StartMyThread(RunSleepThread, "xmrengine sleep", ThreadPriority.Normal);
|
m_SleepThread = StartMyThread(RunSleepThread, "xmrengine sleep", ThreadPriority.Normal);
|
||||||
|
|
||||||
|
@ -678,6 +722,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
XMRScriptThread scriptThread = m_ScriptThreads[i];
|
XMRScriptThread scriptThread = m_ScriptThreads[i];
|
||||||
if (scriptThread != null)
|
if (scriptThread != null)
|
||||||
{
|
{
|
||||||
|
scriptThread.WakeUpScriptThread();
|
||||||
|
Monitor.PulseAll (m_WakeUpLock);
|
||||||
scriptThread.Terminate();
|
scriptThread.Terminate();
|
||||||
m_ScriptThreads[i] = null;
|
m_ScriptThreads[i] = null;
|
||||||
}
|
}
|
||||||
|
@ -722,7 +768,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
m_Scene.EventManager.TriggerEmptyScriptCompileQueue (0, "");
|
m_Scene.EventManager.TriggerEmptyScriptCompileQueue (0, "");
|
||||||
m_StartProcessing = true;
|
m_StartProcessing = true;
|
||||||
for (int i = 0; i < numThreadScriptWorkers; i ++) {
|
for (int i = 0; i < numThreadScriptWorkers; i ++) {
|
||||||
XMRScriptThread.WakeUpOne();
|
WakeUpOne();
|
||||||
}
|
}
|
||||||
m_log.Debug ("[XMREngine]: StartProcessing return");
|
m_log.Debug ("[XMREngine]: StartProcessing return");
|
||||||
}
|
}
|
||||||
|
@ -832,15 +878,18 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
|
|
||||||
case "resume":
|
case "resume":
|
||||||
m_log.Info ("[XMREngine]: resuming scripts");
|
m_log.Info ("[XMREngine]: resuming scripts");
|
||||||
|
m_SuspendScriptThreadFlag = false;
|
||||||
for (int i = 0; i < numThreadScriptWorkers; i ++)
|
for (int i = 0; i < numThreadScriptWorkers; i ++)
|
||||||
m_ScriptThreads[i].ResumeThread();
|
m_ScriptThreads[i].WakeUpScriptThread();
|
||||||
|
Monitor.PulseAll(m_WakeUpLock);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "suspend":
|
case "suspend":
|
||||||
m_log.Info ("[XMREngine]: suspending scripts");
|
m_log.Info ("[XMREngine]: suspending scripts");
|
||||||
|
m_SuspendScriptThreadFlag = true;
|
||||||
for (int i = 0; i < numThreadScriptWorkers; i ++)
|
for (int i = 0; i < numThreadScriptWorkers; i ++)
|
||||||
m_ScriptThreads[i].SuspendThread();
|
m_ScriptThreads[i].WakeUpScriptThread();
|
||||||
|
Monitor.PulseAll(m_WakeUpLock);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "tracecalls":
|
case "tracecalls":
|
||||||
|
@ -1545,7 +1594,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
if (inst.m_IState != XMRInstState.ONSTARTQ) throw new Exception("bad state");
|
if (inst.m_IState != XMRInstState.ONSTARTQ) throw new Exception("bad state");
|
||||||
m_StartQueue.InsertTail(inst);
|
m_StartQueue.InsertTail(inst);
|
||||||
}
|
}
|
||||||
XMRScriptThread.WakeUpOne();
|
WakeUpOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void QueueToTrunk(ThreadStart thds)
|
||||||
|
{
|
||||||
|
lock (m_WakeUpLock)
|
||||||
|
m_ThunkQueue.Enqueue (thds);
|
||||||
|
WakeUpOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1572,7 +1628,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
|
|
||||||
|
|
||||||
// Make sure the OS thread is running so it will see the script.
|
// Make sure the OS thread is running so it will see the script.
|
||||||
XMRScriptThread.WakeUpOne();
|
WakeUpOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1724,7 +1780,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
inst.m_IState = XMRInstState.ONYIELDQ;
|
inst.m_IState = XMRInstState.ONYIELDQ;
|
||||||
m_YieldQueue.InsertTail(inst);
|
m_YieldQueue.InsertTail(inst);
|
||||||
}
|
}
|
||||||
XMRScriptThread.WakeUpOne ();
|
WakeUpOne ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1934,12 +1990,113 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
|
|
||||||
public static void UpdateMyThread ()
|
public static void UpdateMyThread ()
|
||||||
{
|
{
|
||||||
Watchdog.UpdateThread ();
|
Watchdog.UpdateThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MyThreadExiting ()
|
public static void MyThreadExiting ()
|
||||||
{
|
{
|
||||||
Watchdog.RemoveThread (true);
|
Watchdog.RemoveThread(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RunScriptThread(XMRScriptThread xthd)
|
||||||
|
{
|
||||||
|
XMRInstance inst;
|
||||||
|
while (!m_Exiting)
|
||||||
|
{
|
||||||
|
Watchdog.UpdateThread();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle 'xmr resume/suspend' commands.
|
||||||
|
*/
|
||||||
|
if (m_SuspendScriptThreadFlag)
|
||||||
|
{
|
||||||
|
lock (m_WakeUpLock)
|
||||||
|
{
|
||||||
|
while (m_SuspendScriptThreadFlag &&
|
||||||
|
!m_Exiting &&
|
||||||
|
(m_ThunkQueue.Count == 0))
|
||||||
|
{
|
||||||
|
Monitor.Wait (m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2);
|
||||||
|
XMREngine.UpdateMyThread ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maybe there are some scripts waiting to be migrated in or out.
|
||||||
|
*/
|
||||||
|
ThreadStart thunk = null;
|
||||||
|
lock (m_WakeUpLock)
|
||||||
|
{
|
||||||
|
if (m_ThunkQueue.Count > 0)
|
||||||
|
thunk = m_ThunkQueue.Dequeue ();
|
||||||
|
}
|
||||||
|
if (thunk != null)
|
||||||
|
{
|
||||||
|
inst = (XMRInstance)thunk.Target;
|
||||||
|
thunk ();
|
||||||
|
if (m_Exiting || m_SuspendScriptThreadFlag)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_StartProcessing)
|
||||||
|
{
|
||||||
|
// If event just queued to any idle scripts
|
||||||
|
// start them right away. But only start so
|
||||||
|
// many so we can make some progress on yield
|
||||||
|
// queue.
|
||||||
|
|
||||||
|
int numStarts;
|
||||||
|
for (numStarts = 5; -- numStarts >= 0;)
|
||||||
|
{
|
||||||
|
lock (m_StartQueue)
|
||||||
|
{
|
||||||
|
inst = m_StartQueue.RemoveHead();
|
||||||
|
}
|
||||||
|
if (inst == null) break;
|
||||||
|
if (inst.m_IState != XMRInstState.ONSTARTQ) throw new Exception("bad state");
|
||||||
|
xthd.RunInstance (inst);
|
||||||
|
if (m_Exiting || m_SuspendScriptThreadFlag)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is something to run, run it
|
||||||
|
// then rescan from the beginning in case
|
||||||
|
// a lot of things have changed meanwhile.
|
||||||
|
//
|
||||||
|
// These are considered lower priority than
|
||||||
|
// m_StartQueue as they have been taking at
|
||||||
|
// least one quantum of CPU time and event
|
||||||
|
// handlers are supposed to be quick.
|
||||||
|
|
||||||
|
lock (m_YieldQueue)
|
||||||
|
{
|
||||||
|
inst = m_YieldQueue.RemoveHead();
|
||||||
|
}
|
||||||
|
if (inst != null)
|
||||||
|
{
|
||||||
|
if (inst.m_IState != XMRInstState.ONYIELDQ) throw new Exception("bad state");
|
||||||
|
xthd.RunInstance(inst);
|
||||||
|
numStarts = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we left something dangling in the m_StartQueue or m_YieldQueue, go back to check it.
|
||||||
|
if (m_Exiting || numStarts < 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing to do, sleep.
|
||||||
|
lock (m_WakeUpLock)
|
||||||
|
{
|
||||||
|
if (!xthd.m_WakeUpThis && (m_WakeUpOne <= 0) && !m_Exiting)
|
||||||
|
Monitor.Wait(m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2);
|
||||||
|
|
||||||
|
xthd.m_WakeUpThis = false;
|
||||||
|
if ((m_WakeUpOne > 0) && (--m_WakeUpOne > 0))
|
||||||
|
Monitor.Pulse (m_WakeUpLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Watchdog.RemoveThread(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -491,11 +491,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
{
|
{
|
||||||
if (this.newStateCode < 0)
|
if (this.newStateCode < 0)
|
||||||
{
|
{
|
||||||
|
// Process event given by 'stateCode' and 'eventCode'.
|
||||||
|
// The event handler should call CheckRun() as often as convenient.
|
||||||
|
|
||||||
/*
|
|
||||||
* Process event given by 'stateCode' and 'eventCode'.
|
|
||||||
* The event handler should call CheckRun() as often as convenient.
|
|
||||||
*/
|
|
||||||
int newState = this.stateCode;
|
int newState = this.stateCode;
|
||||||
seh = this.m_ObjCode.scriptEventHandlerTable[newState,(int)this.eventCode];
|
seh = this.m_ObjCode.scriptEventHandlerTable[newState,(int)this.eventCode];
|
||||||
if (seh != null)
|
if (seh != null)
|
||||||
|
@ -512,25 +510,19 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
this.ehArgs = null; // we are done with them and no args for
|
this.ehArgs = null; // we are done with them and no args for
|
||||||
// exit_state()/enter_state() anyway
|
// exit_state()/enter_state() anyway
|
||||||
|
|
||||||
/*
|
// The usual case is no state change.
|
||||||
* The usual case is no state change.
|
// Even a 'state <samestate>;' statement has no effect except to exit out.
|
||||||
* Even a 'state <samestate>;' statement has no effect except to exit out.
|
// It does not execute the state_exit() or state_entry() handlers.
|
||||||
* It does not execute the state_exit() or state_entry() handlers.
|
// See http://wiki.secondlife.com/wiki/State
|
||||||
* See http://wiki.secondlife.com/wiki/State
|
|
||||||
*/
|
|
||||||
if (newState == this.stateCode)
|
if (newState == this.stateCode)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
// Save new state in a more permanent location in case we
|
||||||
* Save new state in a more permanent location in case we
|
// get serialized out while in the state_exit() handler.
|
||||||
* get serialized out while in the state_exit() handler.
|
|
||||||
*/
|
|
||||||
this.newStateCode = newState;
|
this.newStateCode = newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Call old state's state_exit() handler.
|
||||||
* Call old state's state_exit() handler.
|
|
||||||
*/
|
|
||||||
this.eventCode = ScriptEventCode.state_exit;
|
this.eventCode = ScriptEventCode.state_exit;
|
||||||
seh = this.m_ObjCode.scriptEventHandlerTable[this.stateCode,(int)ScriptEventCode.state_exit];
|
seh = this.m_ObjCode.scriptEventHandlerTable[this.stateCode,(int)ScriptEventCode.state_exit];
|
||||||
if (seh != null)
|
if (seh != null)
|
||||||
|
@ -545,27 +537,19 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Switch over to the new state's state_entry() handler.
|
||||||
* Switch over to the new state's state_entry() handler.
|
|
||||||
*/
|
|
||||||
this.stateCode = this.newStateCode;
|
this.stateCode = this.newStateCode;
|
||||||
this.eventCode = ScriptEventCode.state_entry;
|
this.eventCode = ScriptEventCode.state_entry;
|
||||||
this.newStateCode = -1;
|
this.newStateCode = -1;
|
||||||
|
|
||||||
/*
|
// Now that the old state can't possibly start any more activity,
|
||||||
* Now that the old state can't possibly start any more activity,
|
// cancel any listening handlers, etc, of the old state.
|
||||||
* cancel any listening handlers, etc, of the old state.
|
|
||||||
*/
|
|
||||||
this.StateChange ();
|
this.StateChange ();
|
||||||
|
|
||||||
/*
|
// Loop back to execute new state's state_entry() handler.
|
||||||
* Loop back to execute new state's state_entry() handler.
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Event no longer being processed.
|
||||||
* Event no longer being processed.
|
|
||||||
*/
|
|
||||||
this.eventCode = ScriptEventCode.None;
|
this.eventCode = ScriptEventCode.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,6 +626,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
* @brief Convert all LSL_Integers in a list to System.Int32s,
|
* @brief Convert all LSL_Integers in a list to System.Int32s,
|
||||||
* as required by llParcelMediaQuery().
|
* as required by llParcelMediaQuery().
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
public static LSL_List FixLLParcelMediaQuery (LSL_List oldlist)
|
public static LSL_List FixLLParcelMediaQuery (LSL_List oldlist)
|
||||||
{
|
{
|
||||||
object[] oldarray = oldlist.Data;
|
object[] oldarray = oldlist.Data;
|
||||||
|
@ -655,11 +640,12 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
}
|
}
|
||||||
return new LSL_List (newarray);
|
return new LSL_List (newarray);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* @brief Convert *SOME* LSL_Integers in a list to System.Int32s,
|
* @brief Convert *SOME* LSL_Integers in a list to System.Int32s,
|
||||||
* as required by llParcelMediaCommandList().
|
* as required by llParcelMediaCommandList().
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
public static LSL_List FixLLParcelMediaCommandList (LSL_List oldlist)
|
public static LSL_List FixLLParcelMediaCommandList (LSL_List oldlist)
|
||||||
{
|
{
|
||||||
object[] oldarray = oldlist.Data;
|
object[] oldarray = oldlist.Data;
|
||||||
|
@ -696,7 +682,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
}
|
}
|
||||||
return new LSL_List (newarray);
|
return new LSL_List (newarray);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
public static int xmrHashCode (int i)
|
public static int xmrHashCode (int i)
|
||||||
{
|
{
|
||||||
return i.GetHashCode ();
|
return i.GetHashCode ();
|
||||||
|
|
|
@ -32,11 +32,6 @@ using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.ScriptEngine.Shared;
|
using OpenSim.Region.ScriptEngine.Shared;
|
||||||
using OpenSim.Region.ScriptEngine.Shared.Api;
|
using OpenSim.Region.ScriptEngine.Shared.Api;
|
||||||
using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
|
|
||||||
using OpenSim.Region.ScriptEngine.XMREngine;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Framework.Scenes.Scripting;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
||||||
|
@ -88,6 +83,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
* -2: no av granted perms
|
* -2: no av granted perms
|
||||||
* -3: av not in region
|
* -3: av not in region
|
||||||
*/
|
*/
|
||||||
|
/* engines should not have own API
|
||||||
public int xmrSeatAvatar (bool owner)
|
public int xmrSeatAvatar (bool owner)
|
||||||
{
|
{
|
||||||
// Get avatar to be seated and make sure they have given us ANIMATION permission
|
// Get avatar to be seated and make sure they have given us ANIMATION permission
|
||||||
|
@ -118,7 +114,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
presence.HandleAgentRequestSit (null, UUID.Zero, m_host.UUID, OpenMetaverse.Vector3.Zero);
|
presence.HandleAgentRequestSit (null, UUID.Zero, m_host.UUID, OpenMetaverse.Vector3.Zero);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* @brief llTeleportAgent() is broken in that if you pass it a landmark,
|
* @brief llTeleportAgent() is broken in that if you pass it a landmark,
|
||||||
* it still subjects the position to spawn points, as it always
|
* it still subjects the position to spawn points, as it always
|
||||||
|
@ -129,6 +125,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
* @param landmark = inventory name or UUID of a landmark object
|
* @param landmark = inventory name or UUID of a landmark object
|
||||||
* @param lookat = looking direction after teleport
|
* @param lookat = looking direction after teleport
|
||||||
*/
|
*/
|
||||||
|
/* engines should not have own API
|
||||||
public void xmrTeleportAgent2Landmark (string agent, string landmark, LSL_Vector lookat)
|
public void xmrTeleportAgent2Landmark (string agent, string landmark, LSL_Vector lookat)
|
||||||
{
|
{
|
||||||
// find out about agent to be teleported
|
// find out about agent to be teleported
|
||||||
|
@ -172,13 +169,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
lookat,
|
lookat,
|
||||||
(uint)TeleportFlags.ViaLandmark);
|
(uint)TeleportFlags.ViaLandmark);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* @brief Allow any member of group given by config SetParcelMusicURLGroup to set music URL.
|
* @brief Allow any member of group given by config SetParcelMusicURLGroup to set music URL.
|
||||||
* Code modelled after llSetParcelMusicURL().
|
* Code modelled after llSetParcelMusicURL().
|
||||||
* @param newurl = new URL to set (or "" to leave it alone)
|
* @param newurl = new URL to set (or "" to leave it alone)
|
||||||
* @returns previous URL string
|
* @returns previous URL string
|
||||||
*/
|
*/
|
||||||
|
/* engines should not have own API
|
||||||
public string xmrSetParcelMusicURLGroup (string newurl)
|
public string xmrSetParcelMusicURLGroup (string newurl)
|
||||||
{
|
{
|
||||||
string groupname = m_ScriptEngine.Config.GetString ("SetParcelMusicURLGroup", "");
|
string groupname = m_ScriptEngine.Config.GetString ("SetParcelMusicURLGroup", "");
|
||||||
|
@ -200,6 +198,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
if ((newurl != null) && (newurl != "")) land.SetMusicUrl (newurl);
|
if ((newurl != null) && (newurl != "")) land.SetMusicUrl (newurl);
|
||||||
return oldurl;
|
return oldurl;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class XMRInstance
|
public partial class XMRInstance
|
||||||
|
|
|
@ -27,22 +27,10 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Reflection;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.Remoting.Lifetime;
|
|
||||||
using System.Security.Policy;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Text;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.ScriptEngine.Interfaces;
|
|
||||||
using OpenSim.Region.ScriptEngine.Shared;
|
using OpenSim.Region.ScriptEngine.Shared;
|
||||||
using OpenSim.Region.ScriptEngine.Shared.Api;
|
using OpenSim.Region.ScriptEngine.Shared.Api;
|
||||||
using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
|
|
||||||
using OpenSim.Region.ScriptEngine.XMREngine;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
||||||
|
@ -78,9 +66,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
*/
|
*/
|
||||||
public XmlElement GetExecutionState(XmlDocument doc)
|
public XmlElement GetExecutionState(XmlDocument doc)
|
||||||
{
|
{
|
||||||
/*
|
// When we're detaching an attachment, we need to wait here.
|
||||||
* When we're detaching an attachment, we need to wait here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Change this to a 5 second timeout. If things do mess up,
|
// Change this to a 5 second timeout. If things do mess up,
|
||||||
// we don't want to be stuck forever.
|
// we don't want to be stuck forever.
|
||||||
|
@ -92,20 +78,16 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
scriptStateN.SetAttribute("Asset", m_Item.AssetID.ToString());
|
scriptStateN.SetAttribute("Asset", m_Item.AssetID.ToString());
|
||||||
scriptStateN.SetAttribute ("SourceHash", m_ObjCode.sourceHash);
|
scriptStateN.SetAttribute ("SourceHash", m_ObjCode.sourceHash);
|
||||||
|
|
||||||
/*
|
// Make sure we aren't executing part of the script so it stays
|
||||||
* Make sure we aren't executing part of the script so it stays
|
// stable. Setting suspendOnCheckRun tells CheckRun() to suspend
|
||||||
* stable. Setting suspendOnCheckRun tells CheckRun() to suspend
|
// and return out so RunOne() will release the lock asap.
|
||||||
* and return out so RunOne() will release the lock asap.
|
|
||||||
*/
|
|
||||||
suspendOnCheckRunHold = true;
|
suspendOnCheckRunHold = true;
|
||||||
lock (m_RunLock)
|
lock (m_RunLock)
|
||||||
{
|
{
|
||||||
m_RunOnePhase = "GetExecutionState enter";
|
m_RunOnePhase = "GetExecutionState enter";
|
||||||
CheckRunLockInvariants(true);
|
CheckRunLockInvariants(true);
|
||||||
|
|
||||||
/*
|
// Get copy of script globals and stack in relocateable form.
|
||||||
* Get copy of script globals and stack in relocateable form.
|
|
||||||
*/
|
|
||||||
MemoryStream snapshotStream = new MemoryStream();
|
MemoryStream snapshotStream = new MemoryStream();
|
||||||
MigrateOutEventHandler(snapshotStream);
|
MigrateOutEventHandler(snapshotStream);
|
||||||
Byte[] snapshotBytes = snapshotStream.ToArray();
|
Byte[] snapshotBytes = snapshotStream.ToArray();
|
||||||
|
@ -116,25 +98,19 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
scriptStateN.AppendChild(snapshotN);
|
scriptStateN.AppendChild(snapshotN);
|
||||||
m_RunOnePhase = "GetExecutionState B"; CheckRunLockInvariants(true);
|
m_RunOnePhase = "GetExecutionState B"; CheckRunLockInvariants(true);
|
||||||
|
|
||||||
/*
|
// "Running" says whether or not we are accepting new events.
|
||||||
* "Running" says whether or not we are accepting new events.
|
|
||||||
*/
|
|
||||||
XmlElement runningN = doc.CreateElement("", "Running", "");
|
XmlElement runningN = doc.CreateElement("", "Running", "");
|
||||||
runningN.AppendChild(doc.CreateTextNode(m_Running.ToString()));
|
runningN.AppendChild(doc.CreateTextNode(m_Running.ToString()));
|
||||||
scriptStateN.AppendChild(runningN);
|
scriptStateN.AppendChild(runningN);
|
||||||
m_RunOnePhase = "GetExecutionState C"; CheckRunLockInvariants(true);
|
m_RunOnePhase = "GetExecutionState C"; CheckRunLockInvariants(true);
|
||||||
|
|
||||||
/*
|
// "DoGblInit" says whether or not default:state_entry() will init global vars.
|
||||||
* "DoGblInit" says whether or not default:state_entry() will init global vars.
|
|
||||||
*/
|
|
||||||
XmlElement doGblInitN = doc.CreateElement("", "DoGblInit", "");
|
XmlElement doGblInitN = doc.CreateElement("", "DoGblInit", "");
|
||||||
doGblInitN.AppendChild(doc.CreateTextNode(doGblInit.ToString()));
|
doGblInitN.AppendChild(doc.CreateTextNode(doGblInit.ToString()));
|
||||||
scriptStateN.AppendChild(doGblInitN);
|
scriptStateN.AppendChild(doGblInitN);
|
||||||
m_RunOnePhase = "GetExecutionState D"; CheckRunLockInvariants(true);
|
m_RunOnePhase = "GetExecutionState D"; CheckRunLockInvariants(true);
|
||||||
|
|
||||||
/*
|
// More misc data.
|
||||||
* More misc data.
|
|
||||||
*/
|
|
||||||
XmlNode permissionsN = doc.CreateElement("", "Permissions", "");
|
XmlNode permissionsN = doc.CreateElement("", "Permissions", "");
|
||||||
scriptStateN.AppendChild(permissionsN);
|
scriptStateN.AppendChild(permissionsN);
|
||||||
|
|
||||||
|
@ -147,10 +123,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
permissionsN.Attributes.Append(maskA);
|
permissionsN.Attributes.Append(maskA);
|
||||||
m_RunOnePhase = "GetExecutionState E"; CheckRunLockInvariants(true);
|
m_RunOnePhase = "GetExecutionState E"; CheckRunLockInvariants(true);
|
||||||
|
|
||||||
/*
|
// "DetectParams" are returned by llDetected...() script functions
|
||||||
* "DetectParams" are returned by llDetected...() script functions
|
// for the currently active event, if any.
|
||||||
* for the currently active event, if any.
|
|
||||||
*/
|
|
||||||
if (m_DetectParams != null)
|
if (m_DetectParams != null)
|
||||||
{
|
{
|
||||||
XmlElement detParArrayN = doc.CreateElement("", "DetectArray", "");
|
XmlElement detParArrayN = doc.CreateElement("", "DetectArray", "");
|
||||||
|
@ -159,16 +133,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
}
|
}
|
||||||
m_RunOnePhase = "GetExecutionState F"; CheckRunLockInvariants(true);
|
m_RunOnePhase = "GetExecutionState F"; CheckRunLockInvariants(true);
|
||||||
|
|
||||||
/*
|
// Save any events we have in the queue.
|
||||||
* Save any events we have in the queue.
|
// <EventQueue>
|
||||||
* <EventQueue>
|
// <Event Name="...">
|
||||||
* <Event Name="...">
|
// <param>...</param> ...
|
||||||
* <param>...</param> ...
|
// <DetectParams>...</DetectParams> ...
|
||||||
* <DetectParams>...</DetectParams> ...
|
// </Event>
|
||||||
* </Event>
|
// ...
|
||||||
* ...
|
// </EventQueue>
|
||||||
* </EventQueue>
|
|
||||||
*/
|
|
||||||
XmlElement queuedEventsN = doc.CreateElement("", "EventQueue", "");
|
XmlElement queuedEventsN = doc.CreateElement("", "EventQueue", "");
|
||||||
lock (m_QueueLock)
|
lock (m_QueueLock)
|
||||||
{
|
{
|
||||||
|
@ -184,31 +156,24 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
scriptStateN.AppendChild(queuedEventsN);
|
scriptStateN.AppendChild(queuedEventsN);
|
||||||
m_RunOnePhase = "GetExecutionState G"; CheckRunLockInvariants(true);
|
m_RunOnePhase = "GetExecutionState G"; CheckRunLockInvariants(true);
|
||||||
|
|
||||||
/*
|
// "Plugins" indicate enabled timers and listens, etc.
|
||||||
* "Plugins" indicate enabled timers and listens, etc.
|
|
||||||
*/
|
|
||||||
Object[] pluginData =
|
Object[] pluginData =
|
||||||
AsyncCommandManager.GetSerializationData(m_Engine,
|
AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID);
|
||||||
m_ItemID);
|
|
||||||
|
|
||||||
XmlNode plugins = doc.CreateElement("", "Plugins", "");
|
XmlNode plugins = doc.CreateElement("", "Plugins", "");
|
||||||
AppendXMLObjectArray(doc, plugins, pluginData, "plugin");
|
AppendXMLObjectArray(doc, plugins, pluginData, "plugin");
|
||||||
scriptStateN.AppendChild(plugins);
|
scriptStateN.AppendChild(plugins);
|
||||||
m_RunOnePhase = "GetExecutionState H"; CheckRunLockInvariants(true);
|
m_RunOnePhase = "GetExecutionState H"; CheckRunLockInvariants(true);
|
||||||
|
|
||||||
/*
|
// Let script run again.
|
||||||
* Let script run again.
|
|
||||||
*/
|
|
||||||
suspendOnCheckRunHold = false;
|
suspendOnCheckRunHold = false;
|
||||||
|
|
||||||
m_RunOnePhase = "GetExecutionState leave";
|
m_RunOnePhase = "GetExecutionState leave";
|
||||||
CheckRunLockInvariants(true);
|
CheckRunLockInvariants(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// scriptStateN represents the contents of the .state file so
|
||||||
* scriptStateN represents the contents of the .state file so
|
// write the .state file while we are here.
|
||||||
* write the .state file while we are here.
|
|
||||||
*/
|
|
||||||
FileStream fs = File.Create(m_StateFileName);
|
FileStream fs = File.Create(m_StateFileName);
|
||||||
StreamWriter sw = new StreamWriter(fs);
|
StreamWriter sw = new StreamWriter(fs);
|
||||||
sw.Write(scriptStateN.OuterXml);
|
sw.Write(scriptStateN.OuterXml);
|
||||||
|
@ -233,32 +198,33 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
// do all the work in the MigrateOutEventHandlerThread() method below
|
// do all the work in the MigrateOutEventHandlerThread() method below
|
||||||
moehstream = stream;
|
moehstream = stream;
|
||||||
|
|
||||||
XMRScriptThread cst = XMRScriptThread.CurrentScriptThread ();
|
XMRScriptThread cst = m_Engine.CurrentScriptThread ();
|
||||||
if (cst != null) {
|
if (cst != null)
|
||||||
|
{
|
||||||
|
|
||||||
// we might be getting called inside some LSL Api function
|
// we might be getting called inside some LSL Api function
|
||||||
// so we are already in script thread and thus must do
|
// so we are already in script thread and thus must do
|
||||||
// migration directly
|
// migration directly
|
||||||
MigrateOutEventHandlerThread ();
|
MigrateOutEventHandlerThread ();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// some other thread, do migration via a script thread
|
// some other thread, do migration via a script thread
|
||||||
lock (XMRScriptThread.m_WakeUpLock) {
|
m_Engine.QueueToTrunk(this.MigrateOutEventHandlerThread);
|
||||||
m_Engine.m_ThunkQueue.Enqueue (this.MigrateOutEventHandlerThread);
|
|
||||||
}
|
|
||||||
XMRScriptThread.WakeUpOne ();
|
|
||||||
|
|
||||||
// wait for it to complete
|
// wait for it to complete
|
||||||
lock (moehdone) {
|
lock (moehdone)
|
||||||
while (moehstream != null) {
|
{
|
||||||
|
while (moehstream != null)
|
||||||
Monitor.Wait (moehdone);
|
Monitor.Wait (moehdone);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// maybe it threw up
|
// maybe it threw up
|
||||||
if (moehexcep != null) throw moehexcep;
|
if (moehexcep != null)
|
||||||
|
throw moehexcep;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Exception moehexcep;
|
private Exception moehexcep;
|
||||||
private object moehdone = new object ();
|
private object moehdone = new object ();
|
||||||
private Stream moehstream;
|
private Stream moehstream;
|
||||||
|
@ -266,64 +232,65 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
{
|
{
|
||||||
Exception except;
|
Exception except;
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
/*
|
// Resume the microthread and it will throw a StackCaptureException()
|
||||||
* Resume the microthread and it will throw a StackCaptureException()
|
// with the stack frames saved to this.stackFrames.
|
||||||
* with the stack frames saved to this.stackFrames.
|
// Then write the saved stack frames to the output stream.
|
||||||
* Then write the saved stack frames to the output stream.
|
//
|
||||||
*
|
// There is a stack only if the event code is not None.
|
||||||
* There is a stack only if the event code is not None.
|
if (this.eventCode != ScriptEventCode.None)
|
||||||
*/
|
{
|
||||||
if (this.eventCode != ScriptEventCode.None) {
|
|
||||||
|
|
||||||
// tell microthread to continue
|
// tell microthread to continue
|
||||||
// it should see captureStackFrames and throw StackCaptureException()
|
// it should see captureStackFrames and throw StackCaptureException()
|
||||||
// ...generating XMRStackFrames as it unwinds
|
// ...generating XMRStackFrames as it unwinds
|
||||||
this.captureStackFrames = true;
|
this.captureStackFrames = true;
|
||||||
|
// this.suspendOnCheckRunTemp = true;
|
||||||
except = this.microthread.ResumeEx ();
|
except = this.microthread.ResumeEx ();
|
||||||
this.captureStackFrames = false;
|
this.captureStackFrames = false;
|
||||||
if (except == null) {
|
|
||||||
|
if (except == null)
|
||||||
throw new Exception ("stack save did not complete");
|
throw new Exception ("stack save did not complete");
|
||||||
}
|
|
||||||
if (!(except is StackCaptureException)) {
|
if (!(except is StackCaptureException))
|
||||||
throw except;
|
throw except;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Write script state out, frames and all, to the stream.
|
||||||
* Write script state out, frames and all, to the stream.
|
// Does not change script state.
|
||||||
* Does not change script state.
|
|
||||||
*/
|
|
||||||
moehstream.WriteByte (migrationVersion);
|
moehstream.WriteByte (migrationVersion);
|
||||||
moehstream.WriteByte ((byte)16);
|
moehstream.WriteByte ((byte)16);
|
||||||
this.MigrateOut (new BinaryWriter (moehstream));
|
this.MigrateOut (new BinaryWriter (moehstream));
|
||||||
|
|
||||||
/*
|
// Now restore script stack.
|
||||||
* Now restore script stack.
|
// Microthread will suspend inside CheckRun() when restore is complete.
|
||||||
* Microthread will suspend inside CheckRun() when restore is complete.
|
if (this.eventCode != ScriptEventCode.None)
|
||||||
*/
|
{
|
||||||
if (this.eventCode != ScriptEventCode.None) {
|
|
||||||
this.stackFramesRestored = false;
|
this.stackFramesRestored = false;
|
||||||
except = this.microthread.StartEx ();
|
except = this.microthread.StartEx ();
|
||||||
if (except != null) {
|
|
||||||
throw except;
|
|
||||||
}
|
|
||||||
if (!this.stackFramesRestored) {
|
|
||||||
throw new Exception ("restore after save did not complete");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
moehexcep = e;
|
|
||||||
} finally {
|
|
||||||
|
|
||||||
// make sure CheckRunLockInvariants() won't puque
|
if (except != null)
|
||||||
if (this.microthread.Active () == 0) {
|
throw except;
|
||||||
this.eventCode = ScriptEventCode.None;
|
|
||||||
|
if (!this.stackFramesRestored)
|
||||||
|
throw new Exception ("restore after save did not complete");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
moehexcep = e;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// make sure CheckRunLockInvariants() won't puque
|
||||||
|
if (this.microthread.Active () == 0)
|
||||||
|
this.eventCode = ScriptEventCode.None;
|
||||||
|
|
||||||
// wake the MigrateOutEventHandler() method above
|
// wake the MigrateOutEventHandler() method above
|
||||||
lock (moehdone) {
|
lock (moehdone)
|
||||||
|
{
|
||||||
moehstream = null;
|
moehstream = null;
|
||||||
Monitor.Pulse (moehdone);
|
Monitor.Pulse (moehdone);
|
||||||
}
|
}
|
||||||
|
|
|
@ -695,7 +695,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
// do all the work in the MigrateInEventHandlerThread() method below
|
// do all the work in the MigrateInEventHandlerThread() method below
|
||||||
miehstream = stream;
|
miehstream = stream;
|
||||||
|
|
||||||
XMRScriptThread cst = XMRScriptThread.CurrentScriptThread ();
|
XMRScriptThread cst = m_Engine.CurrentScriptThread ();
|
||||||
if (cst != null)
|
if (cst != null)
|
||||||
{
|
{
|
||||||
// in case we are getting called inside some LSL Api function
|
// in case we are getting called inside some LSL Api function
|
||||||
|
@ -704,11 +704,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// some other thread, do migration via a script thread
|
// some other thread, do migration via a script thread
|
||||||
lock (XMRScriptThread.m_WakeUpLock)
|
m_Engine.QueueToTrunk(this.MigrateInEventHandlerThread);
|
||||||
{
|
|
||||||
m_Engine.m_ThunkQueue.Enqueue (this.MigrateInEventHandlerThread);
|
|
||||||
}
|
|
||||||
XMRScriptThread.WakeUpOne ();
|
|
||||||
|
|
||||||
// wait for it to complete
|
// wait for it to complete
|
||||||
lock (miehdone)
|
lock (miehdone)
|
||||||
|
@ -777,79 +773,5 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* See if permitted by configuration file.
|
|
||||||
* See OSSL_Api.CheckThreatLevelTest().
|
|
||||||
*/
|
|
||||||
public string CheckFetchbinaryAllowed ()
|
|
||||||
{
|
|
||||||
string ownerPerm = m_Engine.Config.GetString ("Allow_fetchbinary", "");
|
|
||||||
UUID ownerID = m_Item.OwnerID;
|
|
||||||
string[] ids = ownerPerm.Split (new char[] { ',' });
|
|
||||||
foreach (string id in ids)
|
|
||||||
{
|
|
||||||
string curuc = id.Trim().ToUpperInvariant();
|
|
||||||
|
|
||||||
switch (curuc)
|
|
||||||
{
|
|
||||||
case "ESTATE_MANAGER":
|
|
||||||
if (m_Engine.m_Scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner (ownerID) &&
|
|
||||||
(m_Engine.m_Scene.RegionInfo.EstateSettings.EstateOwner != ownerID))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "ESTATE_OWNER":
|
|
||||||
if (m_Engine.m_Scene.RegionInfo.EstateSettings.EstateOwner == ownerID)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "PARCEL_GROUP_MEMBER":
|
|
||||||
ILandObject land = m_Engine.m_Scene.LandChannel.GetLandObject (m_Part.AbsolutePosition);
|
|
||||||
if (land.LandData.GroupID == m_Item.GroupID && land.LandData.GroupID != UUID.Zero)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "PARCEL_OWNER":
|
|
||||||
ILandObject Oland = m_Engine.m_Scene.LandChannel.GetLandObject (m_Part.AbsolutePosition);
|
|
||||||
if (Oland.LandData.OwnerID == ownerID)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "TRUE":
|
|
||||||
return null;
|
|
||||||
|
|
||||||
default:
|
|
||||||
UUID uuid;
|
|
||||||
if (UUID.TryParse (curuc, out uuid))
|
|
||||||
if (uuid == ownerID) return null;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string creatorPerm = m_Engine.Config.GetString ("Creators_fetchbinary", "");
|
|
||||||
UUID creatorID = m_Item.CreatorID;
|
|
||||||
ids = creatorPerm.Split (new char[] { ',' });
|
|
||||||
foreach (string id in ids)
|
|
||||||
{
|
|
||||||
string current = id.Trim ();
|
|
||||||
UUID uuid;
|
|
||||||
if (UUID.TryParse (current, out uuid))
|
|
||||||
{
|
|
||||||
if (uuid != UUID.Zero)
|
|
||||||
{
|
|
||||||
if (creatorID == uuid)
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "fetchbinary not enabled for owner " + ownerID + " creator " + creatorID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ using System.Threading;
|
||||||
|
|
||||||
namespace OpenSim.Region.ScriptEngine.XMREngine
|
namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief There are NUMSCRIPTHREADWKRS of these.
|
* @brief There are NUMSCRIPTHREADWKRS of these.
|
||||||
* Each sits in a loop checking the Start and Yield queues for
|
* Each sits in a loop checking the Start and Yield queues for
|
||||||
|
@ -40,35 +39,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
*/
|
*/
|
||||||
public class XMRScriptThread
|
public class XMRScriptThread
|
||||||
{
|
{
|
||||||
private static int m_WakeUpOne = 0;
|
public bool m_WakeUpThis = false;
|
||||||
public static object m_WakeUpLock = new object();
|
|
||||||
private static Dictionary<Thread,XMRScriptThread> m_AllThreads = new Dictionary<Thread,XMRScriptThread> ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Something was just added to the Start or Yield queue so
|
|
||||||
* wake one of the XMRScriptThread instances to run it.
|
|
||||||
*/
|
|
||||||
public static void WakeUpOne()
|
|
||||||
{
|
|
||||||
lock (m_WakeUpLock)
|
|
||||||
{
|
|
||||||
m_WakeUpOne ++;
|
|
||||||
Monitor.Pulse (m_WakeUpLock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static XMRScriptThread CurrentScriptThread ()
|
|
||||||
{
|
|
||||||
XMRScriptThread st;
|
|
||||||
lock (m_AllThreads) {
|
|
||||||
m_AllThreads.TryGetValue (Thread.CurrentThread, out st);
|
|
||||||
}
|
|
||||||
return st;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool m_Exiting = false;
|
|
||||||
private bool m_SuspendScriptThreadFlag = false;
|
|
||||||
private bool m_WakeUpThis = false;
|
|
||||||
public DateTime m_LastRanAt = DateTime.MinValue;
|
public DateTime m_LastRanAt = DateTime.MinValue;
|
||||||
public int m_ScriptThreadTID = 0;
|
public int m_ScriptThreadTID = 0;
|
||||||
public long m_ScriptExecTime = 0;
|
public long m_ScriptExecTime = 0;
|
||||||
|
@ -80,164 +51,43 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
{
|
{
|
||||||
engine = eng;
|
engine = eng;
|
||||||
if(i < 0)
|
if(i < 0)
|
||||||
thd = XMREngine.StartMyThread (RunScriptThread, "xmrengine script", ThreadPriority.Normal);
|
thd = XMREngine.StartMyThread(RunScriptThread, "xmrengine script", ThreadPriority.Normal);
|
||||||
else
|
else
|
||||||
thd = XMREngine.StartMyThread (RunScriptThread, "xmrengineExec" + i.ToString(), ThreadPriority.Normal);
|
thd = XMREngine.StartMyThread(RunScriptThread, "xmrengineExec" + i.ToString(), ThreadPriority.Normal);
|
||||||
lock (m_AllThreads)
|
engine.AddThread(thd, this);
|
||||||
m_AllThreads.Add (thd, this);
|
m_ScriptThreadTID = thd.ManagedThreadId;
|
||||||
}
|
|
||||||
|
|
||||||
public void SuspendThread()
|
|
||||||
{
|
|
||||||
m_SuspendScriptThreadFlag = true;
|
|
||||||
WakeUpScriptThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResumeThread()
|
|
||||||
{
|
|
||||||
m_SuspendScriptThreadFlag = false;
|
|
||||||
WakeUpScriptThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Terminate()
|
public void Terminate()
|
||||||
{
|
{
|
||||||
m_Exiting = true;
|
m_WakeUpThis = true;
|
||||||
WakeUpScriptThread();
|
|
||||||
if(!thd.Join(250))
|
if(!thd.Join(250))
|
||||||
thd.Abort();
|
thd.Abort();
|
||||||
lock (m_AllThreads)
|
|
||||||
m_AllThreads.Remove (thd);
|
engine.RemoveThread(thd);
|
||||||
|
|
||||||
thd = null;
|
thd = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TimeSlice()
|
|
||||||
{
|
|
||||||
XMRInstance instance = m_RunInstance;
|
|
||||||
if (instance != null)
|
|
||||||
instance.suspendOnCheckRunTemp = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Wake up this XMRScriptThread instance.
|
* @brief Wake up this XMRScriptThread instance.
|
||||||
*/
|
*/
|
||||||
private void WakeUpScriptThread()
|
public void WakeUpScriptThread()
|
||||||
{
|
{
|
||||||
lock (m_WakeUpLock)
|
|
||||||
{
|
|
||||||
m_WakeUpThis = true;
|
m_WakeUpThis = true;
|
||||||
Monitor.PulseAll (m_WakeUpLock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Thread that runs the scripts.
|
|
||||||
*/
|
|
||||||
private void RunScriptThread()
|
|
||||||
{
|
|
||||||
XMRInstance inst;
|
|
||||||
m_ScriptThreadTID = System.Threading.Thread.CurrentThread.ManagedThreadId;
|
|
||||||
|
|
||||||
while (!m_Exiting)
|
|
||||||
{
|
|
||||||
XMREngine.UpdateMyThread ();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handle 'xmr resume/suspend' commands.
|
|
||||||
*/
|
|
||||||
if (m_SuspendScriptThreadFlag)
|
|
||||||
{
|
|
||||||
lock (m_WakeUpLock) {
|
|
||||||
while (m_SuspendScriptThreadFlag &&
|
|
||||||
!m_Exiting &&
|
|
||||||
(engine.m_ThunkQueue.Count == 0))
|
|
||||||
{
|
|
||||||
Monitor.Wait (m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2);
|
|
||||||
XMREngine.UpdateMyThread ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Maybe there are some scripts waiting to be migrated in or out.
|
|
||||||
*/
|
|
||||||
ThreadStart thunk = null;
|
|
||||||
lock (m_WakeUpLock)
|
|
||||||
{
|
|
||||||
if (engine.m_ThunkQueue.Count > 0)
|
|
||||||
thunk = engine.m_ThunkQueue.Dequeue ();
|
|
||||||
}
|
|
||||||
if (thunk != null)
|
|
||||||
{
|
|
||||||
inst = (XMRInstance)thunk.Target;
|
|
||||||
thunk ();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (engine.m_StartProcessing)
|
|
||||||
{
|
|
||||||
// If event just queued to any idle scripts
|
|
||||||
// start them right away. But only start so
|
|
||||||
// many so we can make some progress on yield
|
|
||||||
// queue.
|
|
||||||
|
|
||||||
int numStarts;
|
|
||||||
for (numStarts = 5; -- numStarts >= 0;)
|
|
||||||
{
|
|
||||||
lock (engine.m_StartQueue)
|
|
||||||
{
|
|
||||||
inst = engine.m_StartQueue.RemoveHead();
|
|
||||||
}
|
|
||||||
if (inst == null) break;
|
|
||||||
if (inst.m_IState != XMRInstState.ONSTARTQ) throw new Exception("bad state");
|
|
||||||
RunInstance (inst);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is something to run, run it
|
|
||||||
// then rescan from the beginning in case
|
|
||||||
// a lot of things have changed meanwhile.
|
|
||||||
//
|
|
||||||
// These are considered lower priority than
|
|
||||||
// m_StartQueue as they have been taking at
|
|
||||||
// least one quantum of CPU time and event
|
|
||||||
// handlers are supposed to be quick.
|
|
||||||
|
|
||||||
lock (engine.m_YieldQueue)
|
|
||||||
{
|
|
||||||
inst = engine.m_YieldQueue.RemoveHead();
|
|
||||||
}
|
|
||||||
if (inst != null)
|
|
||||||
{
|
|
||||||
if (inst.m_IState != XMRInstState.ONYIELDQ) throw new Exception("bad state");
|
|
||||||
RunInstance(inst);
|
|
||||||
numStarts = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we left something dangling in the m_StartQueue or m_YieldQueue, go back to check it.
|
|
||||||
if (numStarts < 0)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nothing to do, sleep.
|
|
||||||
|
|
||||||
lock (m_WakeUpLock)
|
|
||||||
{
|
|
||||||
if (!m_WakeUpThis && (m_WakeUpOne <= 0) && !m_Exiting)
|
|
||||||
Monitor.Wait(m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2);
|
|
||||||
|
|
||||||
m_WakeUpThis = false;
|
|
||||||
if ((m_WakeUpOne > 0) && (-- m_WakeUpOne > 0))
|
|
||||||
Monitor.Pulse (m_WakeUpLock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
XMREngine.MyThreadExiting ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A script instance was just removed from the Start or Yield Queue.
|
* @brief A script instance was just removed from the Start or Yield Queue.
|
||||||
* So run it for a little bit then stick in whatever queue it should go in.
|
* So run it for a little bit then stick in whatever queue it should go in.
|
||||||
*/
|
*/
|
||||||
private void RunInstance (XMRInstance inst)
|
|
||||||
|
private void RunScriptThread()
|
||||||
|
{
|
||||||
|
engine.RunScriptThread(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RunInstance (XMRInstance inst)
|
||||||
{
|
{
|
||||||
m_LastRanAt = DateTime.UtcNow;
|
m_LastRanAt = DateTime.UtcNow;
|
||||||
m_ScriptExecTime -= (long)(m_LastRanAt - DateTime.MinValue).TotalMilliseconds;
|
m_ScriptExecTime -= (long)(m_LastRanAt - DateTime.MinValue).TotalMilliseconds;
|
||||||
|
|
|
@ -57,21 +57,28 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
public Exception StartEx ()
|
public Exception StartEx ()
|
||||||
{
|
{
|
||||||
// We should only be called when no event handler running.
|
// We should only be called when no event handler running.
|
||||||
if (active != 0) throw new Exception ("active=" + active);
|
if (active != 0)
|
||||||
|
throw new Exception ("active=" + active);
|
||||||
|
|
||||||
// Start script event handler from very beginning.
|
// Start script event handler from very beginning.
|
||||||
active = 1;
|
active = 1;
|
||||||
Exception except = null;
|
Exception except = null;
|
||||||
instance.callMode = XMRInstance.CallMode_NORMAL;
|
instance.callMode = XMRInstance.CallMode_NORMAL;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
instance.CallSEH (); // run script event handler
|
instance.CallSEH (); // run script event handler
|
||||||
active = 0;
|
active = 0;
|
||||||
} catch (StackHibernateException) {
|
}
|
||||||
if (instance.callMode != XMRInstance.CallMode_SAVE) {
|
catch (StackHibernateException)
|
||||||
|
{
|
||||||
|
if (instance.callMode != XMRInstance.CallMode_SAVE)
|
||||||
|
{
|
||||||
throw new Exception ("callMode=" + instance.callMode);
|
throw new Exception ("callMode=" + instance.callMode);
|
||||||
}
|
}
|
||||||
active = -1; // it is hibernating, can be resumed
|
active = -1; // it is hibernating, can be resumed
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
active = 0;
|
active = 0;
|
||||||
except = e; // threw exception, save for Start()/Resume()
|
except = e; // threw exception, save for Start()/Resume()
|
||||||
}
|
}
|
||||||
|
@ -88,21 +95,28 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
public Exception ResumeEx ()
|
public Exception ResumeEx ()
|
||||||
{
|
{
|
||||||
// We should only be called when script is hibernating.
|
// We should only be called when script is hibernating.
|
||||||
if (active >= 0) throw new Exception ("active=" + active);
|
if (active >= 0)
|
||||||
|
throw new Exception ("active=" + active);
|
||||||
|
|
||||||
// Resume script from captured stack.
|
// Resume script from captured stack.
|
||||||
instance.callMode = XMRInstance.CallMode_RESTORE;
|
instance.callMode = XMRInstance.CallMode_RESTORE;
|
||||||
instance.suspendOnCheckRunTemp = true;
|
instance.suspendOnCheckRunTemp = true;
|
||||||
Exception except = null;
|
Exception except = null;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
instance.CallSEH (); // run script event handler
|
instance.CallSEH (); // run script event handler
|
||||||
active = 0;
|
active = 0;
|
||||||
} catch (StackHibernateException) {
|
}
|
||||||
if (instance.callMode != XMRInstance.CallMode_SAVE) {
|
catch (StackHibernateException)
|
||||||
|
{
|
||||||
|
if (instance.callMode != XMRInstance.CallMode_SAVE)
|
||||||
|
{
|
||||||
throw new Exception ("callMode=" + instance.callMode);
|
throw new Exception ("callMode=" + instance.callMode);
|
||||||
}
|
}
|
||||||
active = -1;
|
active = -1;
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
active = 0;
|
active = 0;
|
||||||
except = e; // threw exception, save for Start()/Resume()
|
except = e; // threw exception, save for Start()/Resume()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue