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.
|
||||
*/
|
||||
public class TokenDeclInline_BEApi : TokenDeclInline {
|
||||
private static readonly MethodInfo fixLLParcelMediaQuery = ScriptCodeGen.GetStaticMethod
|
||||
(typeof (XMRInstAbstract), "FixLLParcelMediaQuery", new Type[] { typeof (LSL_List) });
|
||||
// private static readonly MethodInfo fixLLParcelMediaQuery = ScriptCodeGen.GetStaticMethod
|
||||
// (typeof (XMRInstAbstract), "FixLLParcelMediaQuery", new Type[] { typeof (LSL_List) });
|
||||
|
||||
private static readonly MethodInfo fixLLParcelMediaCommandList = ScriptCodeGen.GetStaticMethod
|
||||
(typeof (XMRInstAbstract), "FixLLParcelMediaCommandList", new Type[] { typeof (LSL_List) });
|
||||
// private static readonly MethodInfo fixLLParcelMediaCommandList = ScriptCodeGen.GetStaticMethod
|
||||
// (typeof (XMRInstAbstract), "FixLLParcelMediaCommandList", new Type[] { typeof (LSL_List) });
|
||||
|
||||
public bool doCheckRun;
|
||||
private FieldInfo apiContextField;
|
||||
|
@ -626,39 +626,41 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
*/
|
||||
public override void CodeGen (ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args)
|
||||
{
|
||||
if (isTaggedCallsCheckRun) { // see if 'xmr' method that calls CheckRun() internally
|
||||
new ScriptCodeGen.CallLabel (scg, errorAt); // if so, put a call label immediately before it
|
||||
// .. so restoring the frame will jump immediately to the
|
||||
// .. call without re-executing any code before this
|
||||
if (isTaggedCallsCheckRun)
|
||||
{ // see if 'xmr' method that calls CheckRun() internally
|
||||
new ScriptCodeGen.CallLabel (scg, errorAt); // if so, put a call label immediately before it
|
||||
// .. 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
|
||||
if (apiContextField != null) {
|
||||
if (apiContextField != null) // 'this' pointer for API function
|
||||
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]);
|
||||
}
|
||||
if (methInfo.Name == "llParcelMediaQuery") {
|
||||
scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaQuery);
|
||||
}
|
||||
if (methInfo.Name == "llParcelMediaCommandList") {
|
||||
scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaCommandList);
|
||||
}
|
||||
if (methInfo.IsVirtual) { // call API function
|
||||
|
||||
// this should not be needed
|
||||
// if (methInfo.Name == "llParcelMediaQuery") {
|
||||
// scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaQuery);
|
||||
// }
|
||||
// this should not be needed
|
||||
// if (methInfo.Name == "llParcelMediaCommandList") {
|
||||
// scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaCommandList);
|
||||
// }
|
||||
if (methInfo.IsVirtual) // call API function
|
||||
scg.ilGen.Emit (errorAt, OpCodes.Callvirt, methInfo);
|
||||
} else {
|
||||
else
|
||||
scg.ilGen.Emit (errorAt, OpCodes.Call, methInfo);
|
||||
}
|
||||
|
||||
result.Pop (scg, errorAt, retType); // pop result, boxing/unboxing as needed
|
||||
if (isTaggedCallsCheckRun) {
|
||||
if (isTaggedCallsCheckRun)
|
||||
scg.openCallLabel = null;
|
||||
}
|
||||
if (doCheckRun) {
|
||||
|
||||
if (doCheckRun)
|
||||
scg.EmitCallCheckRun (errorAt, false); // maybe call CheckRun()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,7 +99,18 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
new Dictionary<string,FieldInfo> ();
|
||||
private int m_StackSize;
|
||||
private int m_HeapSize;
|
||||
|
||||
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 bool m_Exiting = false;
|
||||
|
||||
|
@ -165,6 +176,36 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
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)
|
||||
{
|
||||
TraceCalls("[XMREngine]: Initialize entry");
|
||||
|
@ -235,7 +276,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -678,6 +722,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
XMRScriptThread scriptThread = m_ScriptThreads[i];
|
||||
if (scriptThread != null)
|
||||
{
|
||||
scriptThread.WakeUpScriptThread();
|
||||
Monitor.PulseAll (m_WakeUpLock);
|
||||
scriptThread.Terminate();
|
||||
m_ScriptThreads[i] = null;
|
||||
}
|
||||
|
@ -722,7 +768,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
m_Scene.EventManager.TriggerEmptyScriptCompileQueue (0, "");
|
||||
m_StartProcessing = true;
|
||||
for (int i = 0; i < numThreadScriptWorkers; i ++) {
|
||||
XMRScriptThread.WakeUpOne();
|
||||
WakeUpOne();
|
||||
}
|
||||
m_log.Debug ("[XMREngine]: StartProcessing return");
|
||||
}
|
||||
|
@ -832,15 +878,18 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
|
||||
case "resume":
|
||||
m_log.Info ("[XMREngine]: resuming scripts");
|
||||
m_SuspendScriptThreadFlag = false;
|
||||
for (int i = 0; i < numThreadScriptWorkers; i ++)
|
||||
m_ScriptThreads[i].ResumeThread();
|
||||
|
||||
m_ScriptThreads[i].WakeUpScriptThread();
|
||||
Monitor.PulseAll(m_WakeUpLock);
|
||||
break;
|
||||
|
||||
case "suspend":
|
||||
m_log.Info ("[XMREngine]: suspending scripts");
|
||||
m_SuspendScriptThreadFlag = true;
|
||||
for (int i = 0; i < numThreadScriptWorkers; i ++)
|
||||
m_ScriptThreads[i].SuspendThread();
|
||||
m_ScriptThreads[i].WakeUpScriptThread();
|
||||
Monitor.PulseAll(m_WakeUpLock);
|
||||
break;
|
||||
|
||||
case "tracecalls":
|
||||
|
@ -1545,7 +1594,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
if (inst.m_IState != XMRInstState.ONSTARTQ) throw new Exception("bad state");
|
||||
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.
|
||||
XMRScriptThread.WakeUpOne();
|
||||
WakeUpOne();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1724,7 +1780,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
inst.m_IState = XMRInstState.ONYIELDQ;
|
||||
m_YieldQueue.InsertTail(inst);
|
||||
}
|
||||
XMRScriptThread.WakeUpOne ();
|
||||
WakeUpOne ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1934,12 +1990,113 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
|
||||
public static void UpdateMyThread ()
|
||||
{
|
||||
Watchdog.UpdateThread ();
|
||||
Watchdog.UpdateThread();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// 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;
|
||||
seh = this.m_ObjCode.scriptEventHandlerTable[newState,(int)this.eventCode];
|
||||
if (seh != null)
|
||||
|
@ -512,25 +510,19 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
this.ehArgs = null; // we are done with them and no args for
|
||||
// exit_state()/enter_state() anyway
|
||||
|
||||
/*
|
||||
* The usual case is no state change.
|
||||
* Even a 'state <samestate>;' statement has no effect except to exit out.
|
||||
* It does not execute the state_exit() or state_entry() handlers.
|
||||
* See http://wiki.secondlife.com/wiki/State
|
||||
*/
|
||||
// The usual case is no state change.
|
||||
// Even a 'state <samestate>;' statement has no effect except to exit out.
|
||||
// It does not execute the state_exit() or state_entry() handlers.
|
||||
// See http://wiki.secondlife.com/wiki/State
|
||||
if (newState == this.stateCode)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Save new state in a more permanent location in case we
|
||||
* get serialized out while in the state_exit() handler.
|
||||
*/
|
||||
// Save new state in a more permanent location in case we
|
||||
// get serialized out while in the state_exit() handler.
|
||||
this.newStateCode = newState;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call old state's state_exit() handler.
|
||||
*/
|
||||
// Call old state's state_exit() handler.
|
||||
this.eventCode = ScriptEventCode.state_exit;
|
||||
seh = this.m_ObjCode.scriptEventHandlerTable[this.stateCode,(int)ScriptEventCode.state_exit];
|
||||
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.eventCode = ScriptEventCode.state_entry;
|
||||
this.newStateCode = -1;
|
||||
|
||||
/*
|
||||
* Now that the old state can't possibly start any more activity,
|
||||
* cancel any listening handlers, etc, of the old state.
|
||||
*/
|
||||
// Now that the old state can't possibly start any more activity,
|
||||
// cancel any listening handlers, etc, of the old state.
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -642,6 +626,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
* @brief Convert all LSL_Integers in a list to System.Int32s,
|
||||
* as required by llParcelMediaQuery().
|
||||
*/
|
||||
/*
|
||||
public static LSL_List FixLLParcelMediaQuery (LSL_List oldlist)
|
||||
{
|
||||
object[] oldarray = oldlist.Data;
|
||||
|
@ -655,11 +640,12 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
}
|
||||
return new LSL_List (newarray);
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* @brief Convert *SOME* LSL_Integers in a list to System.Int32s,
|
||||
* as required by llParcelMediaCommandList().
|
||||
*/
|
||||
/*
|
||||
public static LSL_List FixLLParcelMediaCommandList (LSL_List oldlist)
|
||||
{
|
||||
object[] oldarray = oldlist.Data;
|
||||
|
@ -696,7 +682,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
}
|
||||
return new LSL_List (newarray);
|
||||
}
|
||||
|
||||
*/
|
||||
public static int xmrHashCode (int i)
|
||||
{
|
||||
return i.GetHashCode ();
|
||||
|
|
|
@ -32,11 +32,6 @@ using OpenMetaverse;
|
|||
using OpenSim.Framework;
|
||||
using OpenSim.Region.ScriptEngine.Shared;
|
||||
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 LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
||||
|
@ -88,6 +83,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
* -2: no av granted perms
|
||||
* -3: av not in region
|
||||
*/
|
||||
/* engines should not have own API
|
||||
public int xmrSeatAvatar (bool owner)
|
||||
{
|
||||
// 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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* @brief llTeleportAgent() is broken in that if you pass it a landmark,
|
||||
* 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 lookat = looking direction after teleport
|
||||
*/
|
||||
/* engines should not have own API
|
||||
public void xmrTeleportAgent2Landmark (string agent, string landmark, LSL_Vector lookat)
|
||||
{
|
||||
// find out about agent to be teleported
|
||||
|
@ -172,13 +169,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
lookat,
|
||||
(uint)TeleportFlags.ViaLandmark);
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* @brief Allow any member of group given by config SetParcelMusicURLGroup to set music URL.
|
||||
* Code modelled after llSetParcelMusicURL().
|
||||
* @param newurl = new URL to set (or "" to leave it alone)
|
||||
* @returns previous URL string
|
||||
*/
|
||||
/* engines should not have own API
|
||||
public string xmrSetParcelMusicURLGroup (string newurl)
|
||||
{
|
||||
string groupname = m_ScriptEngine.Config.GetString ("SetParcelMusicURLGroup", "");
|
||||
|
@ -200,6 +198,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
if ((newurl != null) && (newurl != "")) land.SetMusicUrl (newurl);
|
||||
return oldurl;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public partial class XMRInstance
|
||||
|
|
|
@ -27,22 +27,10 @@
|
|||
|
||||
using System;
|
||||
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.Xml;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.ScriptEngine.Interfaces;
|
||||
using OpenSim.Region.ScriptEngine.Shared;
|
||||
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 LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
||||
|
@ -78,9 +66,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
*/
|
||||
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,
|
||||
// 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 ("SourceHash", m_ObjCode.sourceHash);
|
||||
|
||||
/*
|
||||
* Make sure we aren't executing part of the script so it stays
|
||||
* stable. Setting suspendOnCheckRun tells CheckRun() to suspend
|
||||
* and return out so RunOne() will release the lock asap.
|
||||
*/
|
||||
// Make sure we aren't executing part of the script so it stays
|
||||
// stable. Setting suspendOnCheckRun tells CheckRun() to suspend
|
||||
// and return out so RunOne() will release the lock asap.
|
||||
suspendOnCheckRunHold = true;
|
||||
lock (m_RunLock)
|
||||
{
|
||||
m_RunOnePhase = "GetExecutionState enter";
|
||||
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();
|
||||
MigrateOutEventHandler(snapshotStream);
|
||||
Byte[] snapshotBytes = snapshotStream.ToArray();
|
||||
|
@ -116,25 +98,19 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
scriptStateN.AppendChild(snapshotN);
|
||||
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", "");
|
||||
runningN.AppendChild(doc.CreateTextNode(m_Running.ToString()));
|
||||
scriptStateN.AppendChild(runningN);
|
||||
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", "");
|
||||
doGblInitN.AppendChild(doc.CreateTextNode(doGblInit.ToString()));
|
||||
scriptStateN.AppendChild(doGblInitN);
|
||||
m_RunOnePhase = "GetExecutionState D"; CheckRunLockInvariants(true);
|
||||
|
||||
/*
|
||||
* More misc data.
|
||||
*/
|
||||
// More misc data.
|
||||
XmlNode permissionsN = doc.CreateElement("", "Permissions", "");
|
||||
scriptStateN.AppendChild(permissionsN);
|
||||
|
||||
|
@ -147,10 +123,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
permissionsN.Attributes.Append(maskA);
|
||||
m_RunOnePhase = "GetExecutionState E"; CheckRunLockInvariants(true);
|
||||
|
||||
/*
|
||||
* "DetectParams" are returned by llDetected...() script functions
|
||||
* for the currently active event, if any.
|
||||
*/
|
||||
// "DetectParams" are returned by llDetected...() script functions
|
||||
// for the currently active event, if any.
|
||||
if (m_DetectParams != null)
|
||||
{
|
||||
XmlElement detParArrayN = doc.CreateElement("", "DetectArray", "");
|
||||
|
@ -159,16 +133,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
}
|
||||
m_RunOnePhase = "GetExecutionState F"; CheckRunLockInvariants(true);
|
||||
|
||||
/*
|
||||
* Save any events we have in the queue.
|
||||
* <EventQueue>
|
||||
* <Event Name="...">
|
||||
* <param>...</param> ...
|
||||
* <DetectParams>...</DetectParams> ...
|
||||
* </Event>
|
||||
* ...
|
||||
* </EventQueue>
|
||||
*/
|
||||
// Save any events we have in the queue.
|
||||
// <EventQueue>
|
||||
// <Event Name="...">
|
||||
// <param>...</param> ...
|
||||
// <DetectParams>...</DetectParams> ...
|
||||
// </Event>
|
||||
// ...
|
||||
// </EventQueue>
|
||||
XmlElement queuedEventsN = doc.CreateElement("", "EventQueue", "");
|
||||
lock (m_QueueLock)
|
||||
{
|
||||
|
@ -184,31 +156,24 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
scriptStateN.AppendChild(queuedEventsN);
|
||||
m_RunOnePhase = "GetExecutionState G"; CheckRunLockInvariants(true);
|
||||
|
||||
/*
|
||||
* "Plugins" indicate enabled timers and listens, etc.
|
||||
*/
|
||||
// "Plugins" indicate enabled timers and listens, etc.
|
||||
Object[] pluginData =
|
||||
AsyncCommandManager.GetSerializationData(m_Engine,
|
||||
m_ItemID);
|
||||
AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID);
|
||||
|
||||
XmlNode plugins = doc.CreateElement("", "Plugins", "");
|
||||
AppendXMLObjectArray(doc, plugins, pluginData, "plugin");
|
||||
scriptStateN.AppendChild(plugins);
|
||||
m_RunOnePhase = "GetExecutionState H"; CheckRunLockInvariants(true);
|
||||
|
||||
/*
|
||||
* Let script run again.
|
||||
*/
|
||||
// Let script run again.
|
||||
suspendOnCheckRunHold = false;
|
||||
|
||||
m_RunOnePhase = "GetExecutionState leave";
|
||||
CheckRunLockInvariants(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* scriptStateN represents the contents of the .state file so
|
||||
* write the .state file while we are here.
|
||||
*/
|
||||
// scriptStateN represents the contents of the .state file so
|
||||
// write the .state file while we are here.
|
||||
FileStream fs = File.Create(m_StateFileName);
|
||||
StreamWriter sw = new StreamWriter(fs);
|
||||
sw.Write(scriptStateN.OuterXml);
|
||||
|
@ -233,32 +198,33 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
// do all the work in the MigrateOutEventHandlerThread() method below
|
||||
moehstream = stream;
|
||||
|
||||
XMRScriptThread cst = XMRScriptThread.CurrentScriptThread ();
|
||||
if (cst != null) {
|
||||
XMRScriptThread cst = m_Engine.CurrentScriptThread ();
|
||||
if (cst != null)
|
||||
{
|
||||
|
||||
// we might be getting called inside some LSL Api function
|
||||
// so we are already in script thread and thus must do
|
||||
// migration directly
|
||||
MigrateOutEventHandlerThread ();
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// some other thread, do migration via a script thread
|
||||
lock (XMRScriptThread.m_WakeUpLock) {
|
||||
m_Engine.m_ThunkQueue.Enqueue (this.MigrateOutEventHandlerThread);
|
||||
}
|
||||
XMRScriptThread.WakeUpOne ();
|
||||
m_Engine.QueueToTrunk(this.MigrateOutEventHandlerThread);
|
||||
|
||||
// wait for it to complete
|
||||
lock (moehdone) {
|
||||
while (moehstream != null) {
|
||||
lock (moehdone)
|
||||
{
|
||||
while (moehstream != null)
|
||||
Monitor.Wait (moehdone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// maybe it threw up
|
||||
if (moehexcep != null) throw moehexcep;
|
||||
if (moehexcep != null)
|
||||
throw moehexcep;
|
||||
}
|
||||
|
||||
private Exception moehexcep;
|
||||
private object moehdone = new object ();
|
||||
private Stream moehstream;
|
||||
|
@ -266,64 +232,65 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
{
|
||||
Exception except;
|
||||
|
||||
try {
|
||||
|
||||
/*
|
||||
* Resume the microthread and it will throw a StackCaptureException()
|
||||
* with the stack frames saved to this.stackFrames.
|
||||
* Then write the saved stack frames to the output stream.
|
||||
*
|
||||
* There is a stack only if the event code is not None.
|
||||
*/
|
||||
if (this.eventCode != ScriptEventCode.None) {
|
||||
|
||||
try
|
||||
{
|
||||
// Resume the microthread and it will throw a StackCaptureException()
|
||||
// with the stack frames saved to this.stackFrames.
|
||||
// Then write the saved stack frames to the output stream.
|
||||
//
|
||||
// There is a stack only if the event code is not None.
|
||||
if (this.eventCode != ScriptEventCode.None)
|
||||
{
|
||||
// tell microthread to continue
|
||||
// it should see captureStackFrames and throw StackCaptureException()
|
||||
// ...generating XMRStackFrames as it unwinds
|
||||
this.captureStackFrames = true;
|
||||
// this.suspendOnCheckRunTemp = true;
|
||||
except = this.microthread.ResumeEx ();
|
||||
this.captureStackFrames = false;
|
||||
if (except == null) {
|
||||
|
||||
if (except == null)
|
||||
throw new Exception ("stack save did not complete");
|
||||
}
|
||||
if (!(except is StackCaptureException)) {
|
||||
|
||||
if (!(except is StackCaptureException))
|
||||
throw except;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write script state out, frames and all, to the stream.
|
||||
* Does not change script state.
|
||||
*/
|
||||
// Write script state out, frames and all, to the stream.
|
||||
// Does not change script state.
|
||||
|
||||
moehstream.WriteByte (migrationVersion);
|
||||
moehstream.WriteByte ((byte)16);
|
||||
this.MigrateOut (new BinaryWriter (moehstream));
|
||||
|
||||
/*
|
||||
* Now restore script stack.
|
||||
* Microthread will suspend inside CheckRun() when restore is complete.
|
||||
*/
|
||||
if (this.eventCode != ScriptEventCode.None) {
|
||||
// Now restore script stack.
|
||||
// Microthread will suspend inside CheckRun() when restore is complete.
|
||||
if (this.eventCode != ScriptEventCode.None)
|
||||
{
|
||||
this.stackFramesRestored = false;
|
||||
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 (this.microthread.Active () == 0) {
|
||||
this.eventCode = ScriptEventCode.None;
|
||||
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 (this.microthread.Active () == 0)
|
||||
this.eventCode = ScriptEventCode.None;
|
||||
|
||||
// wake the MigrateOutEventHandler() method above
|
||||
lock (moehdone) {
|
||||
lock (moehdone)
|
||||
{
|
||||
moehstream = null;
|
||||
Monitor.Pulse (moehdone);
|
||||
}
|
||||
|
|
|
@ -695,7 +695,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
// do all the work in the MigrateInEventHandlerThread() method below
|
||||
miehstream = stream;
|
||||
|
||||
XMRScriptThread cst = XMRScriptThread.CurrentScriptThread ();
|
||||
XMRScriptThread cst = m_Engine.CurrentScriptThread ();
|
||||
if (cst != null)
|
||||
{
|
||||
// in case we are getting called inside some LSL Api function
|
||||
|
@ -704,11 +704,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
else
|
||||
{
|
||||
// some other thread, do migration via a script thread
|
||||
lock (XMRScriptThread.m_WakeUpLock)
|
||||
{
|
||||
m_Engine.m_ThunkQueue.Enqueue (this.MigrateInEventHandlerThread);
|
||||
}
|
||||
XMRScriptThread.WakeUpOne ();
|
||||
m_Engine.QueueToTrunk(this.MigrateInEventHandlerThread);
|
||||
|
||||
// wait for it to complete
|
||||
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
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief There are NUMSCRIPTHREADWKRS of these.
|
||||
* Each sits in a loop checking the Start and Yield queues for
|
||||
|
@ -40,35 +39,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
*/
|
||||
public class XMRScriptThread
|
||||
{
|
||||
private static int m_WakeUpOne = 0;
|
||||
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 bool m_WakeUpThis = false;
|
||||
public DateTime m_LastRanAt = DateTime.MinValue;
|
||||
public int m_ScriptThreadTID = 0;
|
||||
public long m_ScriptExecTime = 0;
|
||||
|
@ -80,164 +51,43 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
{
|
||||
engine = eng;
|
||||
if(i < 0)
|
||||
thd = XMREngine.StartMyThread (RunScriptThread, "xmrengine script", ThreadPriority.Normal);
|
||||
thd = XMREngine.StartMyThread(RunScriptThread, "xmrengine script", ThreadPriority.Normal);
|
||||
else
|
||||
thd = XMREngine.StartMyThread (RunScriptThread, "xmrengineExec" + i.ToString(), ThreadPriority.Normal);
|
||||
lock (m_AllThreads)
|
||||
m_AllThreads.Add (thd, this);
|
||||
}
|
||||
|
||||
public void SuspendThread()
|
||||
{
|
||||
m_SuspendScriptThreadFlag = true;
|
||||
WakeUpScriptThread();
|
||||
}
|
||||
|
||||
public void ResumeThread()
|
||||
{
|
||||
m_SuspendScriptThreadFlag = false;
|
||||
WakeUpScriptThread();
|
||||
thd = XMREngine.StartMyThread(RunScriptThread, "xmrengineExec" + i.ToString(), ThreadPriority.Normal);
|
||||
engine.AddThread(thd, this);
|
||||
m_ScriptThreadTID = thd.ManagedThreadId;
|
||||
}
|
||||
|
||||
public void Terminate()
|
||||
{
|
||||
m_Exiting = true;
|
||||
WakeUpScriptThread();
|
||||
m_WakeUpThis = true;
|
||||
if(!thd.Join(250))
|
||||
thd.Abort();
|
||||
lock (m_AllThreads)
|
||||
m_AllThreads.Remove (thd);
|
||||
|
||||
engine.RemoveThread(thd);
|
||||
|
||||
thd = null;
|
||||
}
|
||||
|
||||
public void TimeSlice()
|
||||
{
|
||||
XMRInstance instance = m_RunInstance;
|
||||
if (instance != null)
|
||||
instance.suspendOnCheckRunTemp = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wake up this XMRScriptThread instance.
|
||||
*/
|
||||
private void WakeUpScriptThread()
|
||||
public void WakeUpScriptThread()
|
||||
{
|
||||
lock (m_WakeUpLock)
|
||||
{
|
||||
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.
|
||||
* 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_ScriptExecTime -= (long)(m_LastRanAt - DateTime.MinValue).TotalMilliseconds;
|
||||
|
|
|
@ -57,21 +57,28 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
public Exception StartEx ()
|
||||
{
|
||||
// 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.
|
||||
active = 1;
|
||||
Exception except = null;
|
||||
instance.callMode = XMRInstance.CallMode_NORMAL;
|
||||
try {
|
||||
try
|
||||
{
|
||||
instance.CallSEH (); // run script event handler
|
||||
active = 0;
|
||||
} catch (StackHibernateException) {
|
||||
if (instance.callMode != XMRInstance.CallMode_SAVE) {
|
||||
}
|
||||
catch (StackHibernateException)
|
||||
{
|
||||
if (instance.callMode != XMRInstance.CallMode_SAVE)
|
||||
{
|
||||
throw new Exception ("callMode=" + instance.callMode);
|
||||
}
|
||||
active = -1; // it is hibernating, can be resumed
|
||||
} catch (Exception e) {
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
active = 0;
|
||||
except = e; // threw exception, save for Start()/Resume()
|
||||
}
|
||||
|
@ -88,21 +95,28 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
public Exception ResumeEx ()
|
||||
{
|
||||
// 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.
|
||||
instance.callMode = XMRInstance.CallMode_RESTORE;
|
||||
instance.suspendOnCheckRunTemp = true;
|
||||
Exception except = null;
|
||||
try {
|
||||
try
|
||||
{
|
||||
instance.CallSEH (); // run script event handler
|
||||
active = 0;
|
||||
} catch (StackHibernateException) {
|
||||
if (instance.callMode != XMRInstance.CallMode_SAVE) {
|
||||
}
|
||||
catch (StackHibernateException)
|
||||
{
|
||||
if (instance.callMode != XMRInstance.CallMode_SAVE)
|
||||
{
|
||||
throw new Exception ("callMode=" + instance.callMode);
|
||||
}
|
||||
active = -1;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
active = 0;
|
||||
except = e; // threw exception, save for Start()/Resume()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue