Added config options:

ScriptThreadPriority to set script thread priority
DeactivateScriptOnTimeout to remove script if it is executing too long
ThreadPoolClientBranch
Tedd Hansen 2008-02-01 20:45:15 +00:00
parent f4ddf5cf28
commit e14c8f59f7
3 changed files with 56 additions and 3 deletions

View File

@ -82,11 +82,13 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
/// </summary>
private int numberOfThreads;
/// <summary>
/// Maximum time one function can use for execution before we perform a thread kill
/// </summary>
private int maxFunctionExecutionTimems;
private bool EnforceMaxExecutionTime;
private bool KillScriptOnMaxFunctionExecutionTime;
/// <summary>
@ -169,7 +171,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
maxFunctionExecutionTimems = m_ScriptEngine.ScriptConfigSource.GetInt("MaxEventExecutionTimeMs", 5000);
EnforceMaxExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("EnforceMaxEventExecutionTime", false);
KillScriptOnMaxFunctionExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("DeactivateScriptOnTimeout", false);
// Start function max exec time enforcement thread
@ -336,6 +338,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
maxFunctionExecutionTimems)
{
// We need to kill this thread!
EventQueueThread.KillCurrentScript = KillScriptOnMaxFunctionExecutionTime;
AbortThreadClass(EventQueueThread);
// Then start another
StartNewThreadClass();

View File

@ -21,10 +21,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
public DateTime LastExecutionStarted;
public bool InExecution = false;
public bool KillCurrentScript = false;
private EventQueueManager eventQueueManager;
public Thread EventQueueThread;
private static int ThreadCount = 0;
private ThreadPriority MyThreadPriority;
public EventQueueThreadClass(EventQueueManager eqm)
{
@ -43,9 +45,36 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
/// </summary>
private void Start()
{
// Later with ScriptServer we might want to ask OS for stuff too, so doing this a bit manually
string pri = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetString("ScriptThreadPriority", "BelowNormal");
switch (pri.ToLower())
{
case "lowest":
MyThreadPriority = ThreadPriority.Lowest;
break;
case "belownormal":
MyThreadPriority = ThreadPriority.BelowNormal;
break;
case "normal":
MyThreadPriority = ThreadPriority.Normal;
break;
case "abovenormal":
MyThreadPriority = ThreadPriority.AboveNormal;
break;
case "highest":
MyThreadPriority = ThreadPriority.Highest;
break;
default:
MyThreadPriority = ThreadPriority.BelowNormal; // Default
eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngineBase", "Unknown priority type \"" + pri + "\" in config file. Defaulting to \"BelowNormal\".");
break;
}
EventQueueThread = new Thread(EventQueueThreadLoop);
EventQueueThread.IsBackground = true;
EventQueueThread.Priority = ThreadPriority.BelowNormal;
EventQueueThread.Priority = MyThreadPriority;
EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount;
EventQueueThread.Start();
@ -134,6 +163,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
+ ", QIS.functionName: " + QIS.functionName);
#endif
LastExecutionStarted = DateTime.Now;
KillCurrentScript = false;
InExecution = true;
eventQueueManager.m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, QIS.itemID,
QIS.functionName, QIS.llDetectParams, QIS.param);
@ -155,6 +185,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
// Send normal
text += e.Message.ToString();
}
if (KillCurrentScript)
text += "\r\nScript will be deactivated!";
try
{
if (text.Length > 1500)
@ -174,6 +207,14 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngine",
"Unable to send text in-world:\r\n" + text);
}
finally
{
// So we are done sending message in-world
if (KillCurrentScript)
{
eventQueueManager.m_ScriptEngine.m_ScriptManager.RemoveScript(QIS.localID, QIS.itemID);
}
}
}
finally
{

View File

@ -127,13 +127,17 @@ shout_distance = 100
; Threads are shared across all regions
NumberOfScriptThreads=2
; Script event execution thread priority inside application.
; Valid values: Lowest, BelowNormal, Normal, AboveNormal, Highest
ScriptThreadPriority=BelowNormal
; Should the script threads be private for each region?
; true: Each region will get <NumberOfScriptThreads> dedicated to scripts within that region
; Number of threads will be <NumberOfScriptThreads>*<NumberOfRegions>
; false: All regions share <NumberOfScriptThreads> for all their scripts
PrivateRegionThreads=false
; How long MAX should a script be allowed to run?
; How long MAX should a script event be allowed to run (per event execution)?
; Do not set this too low (like 50ms) as there are some time wasted in simply executing a function
; There is also a small speed penalty for every kill that is made
MaxEventExecutionTimeMs=5000
@ -141,6 +145,11 @@ MaxEventExecutionTimeMs=5000
; Should we enable the max script event execution thread to look for scripts that exceed their timeslice?
EnforceMaxEventExecutionTime=true
; Should we stop the script completely when time exceeds?
; This is useful if you have a high <MaxEventExecutionTimeMs> and want to deactivate scripts that go wrong
; Note that for example physics engine can slow down the system and make scripts spend more time
DeactivateScriptOnTimeout=false
; If no scripts have executed in this pass how long should we sleep before checking again
; Impact:
; Too low and you will waste lots of CPU