From a040008cb956f4e99bc87a006b51925966443d63 Mon Sep 17 00:00:00 2001 From: Tedd Hansen Date: Fri, 22 Feb 2008 12:50:24 +0000 Subject: From this commit and a few hours into the future ScriptEngine will be unstable: * Speeding up ScriptEngine shutdown * Sharing threads so that minimum total thread count for any amount of regions will be 2. (1 maintenance, 1 script execution) You can choose more script exec threads if you want of course. In this commit: Sharing maintenance thread between all regions. --- .../Common/ScriptEngineBase/EventQueueManager.cs | 18 +++--- .../Common/ScriptEngineBase/MaintenanceThread.cs | 71 ++++++++++++---------- .../Common/ScriptEngineBase/ScriptEngine.cs | 26 ++++---- .../Common/ScriptEngineBase/ScriptManager.cs | 49 +++++++-------- .../iScriptEngineFunctionModule.cs | 2 +- 5 files changed, 87 insertions(+), 79 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs index aa7e3e9..e3d448c 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs @@ -452,14 +452,14 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase } #endregion - /// - /// If set to true then threads and stuff should try to make a graceful exit - /// - public bool PleaseShutdown - { - get { return _PleaseShutdown; } - set { _PleaseShutdown = value; } - } - private bool _PleaseShutdown = false; + ///// + ///// If set to true then threads and stuff should try to make a graceful exit + ///// + //public bool PleaseShutdown + //{ + // get { return _PleaseShutdown; } + // set { _PleaseShutdown = value; } + //} + //private bool _PleaseShutdown = false; } } diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs index f959a5b..1a5cca1 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs @@ -38,12 +38,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase /// public class MaintenanceThread : iScriptEngineFunctionModule { - public ScriptEngine m_ScriptEngine; + //public ScriptEngine m_ScriptEngine; private int MaintenanceLoopms; - public MaintenanceThread(ScriptEngine _ScriptEngine) + public MaintenanceThread() { - m_ScriptEngine = _ScriptEngine; + //m_ScriptEngine = _ScriptEngine; ReadConfig(); @@ -95,9 +95,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase try { if (MaintenanceThreadThread != null && MaintenanceThreadThread.IsAlive) - { - MaintenanceThreadThread.Abort(); - } + { + MaintenanceThreadThread.Abort(); + } } catch (Exception ex) { @@ -105,14 +105,15 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase } } + private ScriptEngine lastScriptEngine; // Keep track of what ScriptEngine instance we are at so we can give exception /// /// A thread should run in this loop and check all running scripts /// public void MaintenanceLoop() { - if (m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens < MaintenanceLoopms) - m_ScriptEngine.Log.Warn("[" + m_ScriptEngine.ScriptEngineName + "]: " + - "Configuration error: MaxEventExecutionTimeMs is less than MaintenanceLoopms. The Maintenance Loop will only check scripts once per run."); + //if (m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens < MaintenanceLoopms) + // m_ScriptEngine.Log.Warn("[" + m_ScriptEngine.ScriptEngineName + "]: " + + // "Configuration error: MaxEventExecutionTimeMs is less than MaintenanceLoopms. The Maintenance Loop will only check scripts once per run."); long Last_maxFunctionExecutionTimens = 0; // DateTime.Now.Ticks; long Last_ReReadConfigFilens = DateTime.Now.Ticks; @@ -126,35 +127,41 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase if (PleaseShutdown) return; - if (m_ScriptEngine != null) + foreach (ScriptEngine m_ScriptEngine in ScriptEngine.ScriptEngines) { - // Re-reading config every x seconds - if (m_ScriptEngine.RefreshConfigFilens > 0) + lastScriptEngine = m_ScriptEngine; + if (m_ScriptEngine != null) { - // Check if its time to re-read config - if (DateTime.Now.Ticks - Last_ReReadConfigFilens > m_ScriptEngine.RefreshConfigFilens) + // Re-reading config every x seconds + if (m_ScriptEngine.RefreshConfigFilens > 0) { - //Console.WriteLine("Time passed: " + (DateTime.Now.Ticks - Last_ReReadConfigFilens) + ">" + m_ScriptEngine.RefreshConfigFilens ); - // Its time to re-read config file - m_ScriptEngine.ReadConfig(); - Last_ReReadConfigFilens = DateTime.Now.Ticks; // Reset time + // Check if its time to re-read config + if (DateTime.Now.Ticks - Last_ReReadConfigFilens > + m_ScriptEngine.RefreshConfigFilens) + { + //Console.WriteLine("Time passed: " + (DateTime.Now.Ticks - Last_ReReadConfigFilens) + ">" + m_ScriptEngine.RefreshConfigFilens ); + // Its time to re-read config file + m_ScriptEngine.ReadConfig(); + Last_ReReadConfigFilens = DateTime.Now.Ticks; // Reset time + } } - } - // Adjust number of running script threads if not correct - if (m_ScriptEngine.m_EventQueueManager != null) - m_ScriptEngine.m_EventQueueManager.AdjustNumberOfScriptThreads(); + // Adjust number of running script threads if not correct + if (m_ScriptEngine.m_EventQueueManager != null) + m_ScriptEngine.m_EventQueueManager.AdjustNumberOfScriptThreads(); - // Check if any script has exceeded its max execution time - if (m_ScriptEngine.m_EventQueueManager != null && m_ScriptEngine.m_EventQueueManager.EnforceMaxExecutionTime) - { - // We are enforcing execution time - if (DateTime.Now.Ticks - Last_maxFunctionExecutionTimens > - m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens) + // Check if any script has exceeded its max execution time + if (m_ScriptEngine.m_EventQueueManager != null && + m_ScriptEngine.m_EventQueueManager.EnforceMaxExecutionTime) { - // Its time to check again - m_ScriptEngine.m_EventQueueManager.CheckScriptMaxExecTime(); // Do check - Last_maxFunctionExecutionTimens = DateTime.Now.Ticks; // Reset time + // We are enforcing execution time + if (DateTime.Now.Ticks - Last_maxFunctionExecutionTimens > + m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens) + { + // Its time to check again + m_ScriptEngine.m_EventQueueManager.CheckScriptMaxExecTime(); // Do check + Last_maxFunctionExecutionTimens = DateTime.Now.Ticks; // Reset time + } } } } @@ -162,7 +169,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase } catch (Exception ex) { - m_ScriptEngine.Log.Error("[" + m_ScriptEngine.ScriptEngineName + "]: Exception in MaintenanceLoopThread. Thread will recover after 5 sec throttle. Exception: " + ex.ToString()); + ScriptEngine.Log.Error("[" + lastScriptEngine.ScriptEngineName + "]: Exception in MaintenanceLoopThread. Thread will recover after 5 sec throttle. Exception: " + ex.ToString()); Thread.Sleep(5000); } } diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs index 3777b67..67eefd9 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs @@ -27,6 +27,7 @@ */ using System; +using System.Collections.Generic; using System.IO; using Nini.Config; using OpenSim.Framework.Console; @@ -46,13 +47,14 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase { private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + public static List ScriptEngines = new List(); public Scene World; public EventManager m_EventManager; // Handles and queues incoming events from OpenSim public EventQueueManager m_EventQueueManager; // Executes events, handles script threads public ScriptManager m_ScriptManager; // Load, unload and execute scripts public AppDomainManager m_AppDomainManager; // Handles loading/unloading of scripts into AppDomains public AsyncLSLCommandManager m_ASYNCLSLCommandManager; // Asyncronous LSL commands (commands that returns with an event) - public MaintenanceThread m_MaintenanceThread; // Thread that does different kinds of maintenance, for example refreshing config and killing scripts that has been running too long + public static MaintenanceThread m_MaintenanceThread; // Thread that does different kinds of maintenance, for example refreshing config and killing scripts that has been running too long public IConfigSource ConfigSource; public IConfig ScriptConfigSource; @@ -74,15 +76,15 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase public abstract ScriptManager _GetScriptManager(); - public log4net.ILog Log + public static log4net.ILog Log { get { return m_log; } } public ScriptEngine() { - //Common.SendToDebug("ScriptEngine Object Initialized"); - Common.mySE = this; + Common.mySE = this; // For logging, just need any instance, doesn't matter + ScriptEngines.Add(this); // Keep a list of ScriptEngines for shared threads to process all instances } public void InitializeEngine(Scene Sceneworld, IConfigSource config, bool HookUpToServer, ScriptManager newScriptManager) @@ -106,7 +108,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase m_ScriptManager = newScriptManager; m_AppDomainManager = new AppDomainManager(this); m_ASYNCLSLCommandManager = new AsyncLSLCommandManager(this); - m_MaintenanceThread = new MaintenanceThread(this); + if (m_MaintenanceThread == null) + m_MaintenanceThread = new MaintenanceThread(); m_log.Info("[" + ScriptEngineName + "]: Reading configuration from config section \"" + ScriptEngineName + "\""); ReadConfig(); @@ -118,6 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase public void Shutdown() { // We are shutting down + ScriptEngines.Remove(this); } ScriptServerInterfaces.RemoteEvents ScriptServerInterfaces.ScriptEngine.EventManager() @@ -178,12 +182,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase /// /// If set to true then threads and stuff should try to make a graceful exit /// - public bool PleaseShutdown - { - get { return _PleaseShutdown; } - set { _PleaseShutdown = value; } - } - private bool _PleaseShutdown = false; + //public bool PleaseShutdown + //{ + // get { return _PleaseShutdown; } + // set { _PleaseShutdown = value; } + //} + //private bool _PleaseShutdown = false; } } diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs index 684d133..b50c184 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs @@ -169,15 +169,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase // Abort load/unload thread try { - PleaseShutdown = true; - Thread.Sleep(100); - if (scriptLoadUnloadThread != null) + //PleaseShutdown = true; + //Thread.Sleep(100); + if (scriptLoadUnloadThread != null && scriptLoadUnloadThread.IsAlive == true) { - if (scriptLoadUnloadThread.IsAlive == true) - { - scriptLoadUnloadThread.Abort(); - scriptLoadUnloadThread.Join(); - } + scriptLoadUnloadThread.Abort(); + //scriptLoadUnloadThread.Join(); } } catch @@ -282,7 +279,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase public abstract void _StartScript(uint localID, LLUUID itemID, string Script); public abstract void _StopScript(uint localID, LLUUID itemID); - + #endregion @@ -297,10 +294,10 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase /// Arguments to pass to function internal void ExecuteEvent(uint localID, LLUUID itemID, string FunctionName, EventQueueManager.Queue_llDetectParams_Struct qParams, object[] args) { -//cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined -///#if DEBUG -/// Console.WriteLine("ScriptEngine: Inside ExecuteEvent for event " + FunctionName); -///#endif + //cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined + ///#if DEBUG + /// Console.WriteLine("ScriptEngine: Inside ExecuteEvent for event " + FunctionName); + ///#endif // Execute a function in the script //m_scriptEngine.Log.Info("[" + ScriptEngineName + "]: Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName); //ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID); @@ -309,10 +306,10 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase { return; } -//cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined -///#if DEBUG -/// Console.WriteLine("ScriptEngine: Executing event: " + FunctionName); -///#endif + //cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined + ///#if DEBUG + /// Console.WriteLine("ScriptEngine: Executing event: " + FunctionName); + ///#endif // Must be done in correct AppDomain, so leaving it up to the script itself Script.llDetectParams = qParams; Script.Exec.ExecuteEvent(FunctionName, args); @@ -418,15 +415,15 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase #endregion - /// - /// If set to true then threads and stuff should try to make a graceful exit - /// - public bool PleaseShutdown - { - get { return _PleaseShutdown; } - set { _PleaseShutdown = value; } - } - private bool _PleaseShutdown = false; + ///// + ///// If set to true then threads and stuff should try to make a graceful exit + ///// + //public bool PleaseShutdown + //{ + // get { return _PleaseShutdown; } + // set { _PleaseShutdown = value; } + //} + //private bool _PleaseShutdown = false; } } diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/iScriptEngineFunctionModule.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/iScriptEngineFunctionModule.cs index 1c730f5..516d76a 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/iScriptEngineFunctionModule.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/iScriptEngineFunctionModule.cs @@ -35,6 +35,6 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase public interface iScriptEngineFunctionModule { void ReadConfig(); - bool PleaseShutdown { get; set; } +// bool PleaseShutdown { get; set; } } } \ No newline at end of file -- cgit v1.1