public void StartThreadWorker() { Thread thd = XMREngine.StartMyThread(RunScriptThread, "xmrengine script", ThreadPriority.BelowNormal); lock (m_WakeUpLock) { m_RunningInstances.Add(thd.ManagedThreadId, null); } }
private void InitScriptApi(XMREngine engine, string api, IScriptApi scriptApi) { /* * Set up m_ApiManager_<APINAME> = instance pointer. */ engine.m_XMRInstanceApiCtxFieldInfos[api].SetValue(this, scriptApi); /* * Initialize the API instance. */ scriptApi.Initialize(m_Engine, m_Part, m_Item); this.InitApi(api, scriptApi); }
/** * @brief Thread that runs the scripts. * * There are NUMSCRIPTHREADWKRS of these. * Each sits in a loop checking the Start and Yield queues for * a script to run and calls the script as a microthread. */ private void RunScriptThread() { int tid = System.Threading.Thread.CurrentThread.ManagedThreadId; ThreadStart thunk; XMRInstance inst; m_ScriptThreadTID = tid; while (!m_Exiting) { XMREngine.UpdateMyThread(); lock (m_WakeUpLock) { /* * Maybe there are some scripts waiting to be migrated in or out. */ thunk = null; if (m_ThunkQueue.Count > 0) { thunk = m_ThunkQueue.Dequeue(); } /* * Handle 'xmr resume/suspend' commands. */ else if (m_SuspendScriptThreadFlag && !m_Exiting) { Monitor.Wait(m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2); XMREngine.UpdateMyThread(); continue; } } if (thunk != null) { thunk(); 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"); } RunInstance(inst, tid); } /* * 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"); } RunInstance(inst, tid); 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); } } } lock (m_WakeUpLock) { m_RunningInstances.Remove(tid); } XMREngine.MyThreadExiting(); }
/****************************************************************************\ * The only method of interest to outside this module is the Initializer. * * * * The rest of this module contains support routines for the Initializer. * \****************************************************************************/ /** * @brief Initializer, loads script in memory and all ready for running. * @param engine = XMREngine instance this is part of * @param scriptBasePath = directory name where files are * @param stackSize = number of bytes to allocate for stacks * @param errors = return compiler errors in this array * @param forceRecomp = force recompile * Throws exception if any error, so it was successful if it returns. */ public void Initialize(XMREngine engine, string scriptBasePath, int stackSize, int heapSize, ArrayList errors) { if (stackSize < 16384) { stackSize = 16384; } if (heapSize < 16384) { heapSize = 16384; } /* * Save all call parameters in instance vars for easy access. */ m_Engine = engine; m_ScriptBasePath = scriptBasePath; m_StackSize = stackSize; m_StackLeft = stackSize; m_HeapSize = heapSize; m_CompilerErrors = errors; m_StateFileName = GetStateFileName(scriptBasePath, m_ItemID); /* * Not in any XMRInstQueue. */ m_NextInst = this; m_PrevInst = this; /* * Set up list of API calls it has available. * This also gets the API modules ready to accept setup data, such as * active listeners being restored. */ IScriptApi scriptApi; ApiManager am = new ApiManager(); foreach (string api in am.GetApis()) { /* * Instantiate the API for this script instance. */ if (api != "LSL") { scriptApi = am.CreateApi(api); } else { scriptApi = m_XMRLSLApi = new XMRLSL_Api(); } /* * Connect it up to the instance. */ InitScriptApi(engine, api, scriptApi); } m_XMRLSLApi.InitXMRLSLApi(this); /* * Get object loaded, compiling script and reading .state file as * necessary to restore the state. */ suspendOnCheckRunHold = true; InstantiateScript(); m_SourceCode = null; if (m_ObjCode == null) { throw new ArgumentNullException("m_ObjCode"); } if (m_ObjCode.scriptEventHandlerTable == null) { throw new ArgumentNullException("m_ObjCode.scriptEventHandlerTable"); } suspendOnCheckRunHold = false; suspendOnCheckRunTemp = false; /* * Declare which events the script's current state can handle. */ int eventMask = GetStateEventFlags(stateCode); m_Part.SetScriptEvents(m_ItemID, eventMask); }