private void InitScriptApi(Yengine 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); }
public void StartThreadWorker(int i) { Thread thd; if (i >= 0) { thd = Yengine.StartMyThread(RunScriptThread, "YScript" + i.ToString(), ThreadPriority.BelowNormal); } else { thd = Yengine.StartMyThread(RunScriptThread, "YScript", ThreadPriority.BelowNormal); } lock (m_WakeUpLock) m_RunningInstances.Add(thd.ManagedThreadId, null); }
public void StartThreadWorker(int i, ThreadPriority priority, string sceneName) { Thread thd; if (i >= 0) { thd = Yengine.StartMyThread(RunScriptThread, "YScript" + i.ToString() + " (" + sceneName + ")", priority); } else { thd = Yengine.StartMyThread(RunScriptThread, "YScript", priority); } lock (m_WakeUpLock) m_RunningInstances.Add(thd.ManagedThreadId, null); }
/****************************************************************************\ * 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 = YEngine 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(Yengine 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_localsHeapUsed = 0; m_arraysHeapUsed = 0; 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; }
/** * @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; bool didevent; m_ScriptThreadTID = tid; while (!m_Exiting) { Yengine.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); Yengine.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; didevent = false; for (numStarts = 5; numStarts >= 0; --numStarts) { lock (m_StartQueue) inst = m_StartQueue.RemoveHead(); if (inst == null) { break; } if (inst.m_IState == XMRInstState.SUSPENDED) { continue; } if (inst.m_IState != XMRInstState.ONSTARTQ) { throw new Exception("bad state"); } RunInstance(inst, tid); if (m_SuspendScriptThreadFlag || m_Exiting) { continue; } didevent = true; } // 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.SUSPENDED) { continue; } if (inst.m_IState != XMRInstState.ONYIELDQ) { throw new Exception("bad state"); } RunInstance(inst, tid); continue; } // If we left something dangling in the m_StartQueue or m_YieldQueue, go back to check it. if (didevent) { 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); Yengine.MyThreadExiting(); }