Added config options:
ScriptThreadPriority to set script thread priority DeactivateScriptOnTimeout to remove script if it is executing too longThreadPoolClientBranch
parent
f4ddf5cf28
commit
e14c8f59f7
|
@ -82,11 +82,13 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private int numberOfThreads;
|
private int numberOfThreads;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maximum time one function can use for execution before we perform a thread kill
|
/// Maximum time one function can use for execution before we perform a thread kill
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private int maxFunctionExecutionTimems;
|
private int maxFunctionExecutionTimems;
|
||||||
private bool EnforceMaxExecutionTime;
|
private bool EnforceMaxExecutionTime;
|
||||||
|
private bool KillScriptOnMaxFunctionExecutionTime;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -169,7 +171,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
|
|
||||||
maxFunctionExecutionTimems = m_ScriptEngine.ScriptConfigSource.GetInt("MaxEventExecutionTimeMs", 5000);
|
maxFunctionExecutionTimems = m_ScriptEngine.ScriptConfigSource.GetInt("MaxEventExecutionTimeMs", 5000);
|
||||||
EnforceMaxExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("EnforceMaxEventExecutionTime", false);
|
EnforceMaxExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("EnforceMaxEventExecutionTime", false);
|
||||||
|
KillScriptOnMaxFunctionExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("DeactivateScriptOnTimeout", false);
|
||||||
|
|
||||||
|
|
||||||
// Start function max exec time enforcement thread
|
// Start function max exec time enforcement thread
|
||||||
|
@ -336,6 +338,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
maxFunctionExecutionTimems)
|
maxFunctionExecutionTimems)
|
||||||
{
|
{
|
||||||
// We need to kill this thread!
|
// We need to kill this thread!
|
||||||
|
EventQueueThread.KillCurrentScript = KillScriptOnMaxFunctionExecutionTime;
|
||||||
AbortThreadClass(EventQueueThread);
|
AbortThreadClass(EventQueueThread);
|
||||||
// Then start another
|
// Then start another
|
||||||
StartNewThreadClass();
|
StartNewThreadClass();
|
||||||
|
|
|
@ -21,10 +21,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
|
|
||||||
public DateTime LastExecutionStarted;
|
public DateTime LastExecutionStarted;
|
||||||
public bool InExecution = false;
|
public bool InExecution = false;
|
||||||
|
public bool KillCurrentScript = false;
|
||||||
|
|
||||||
private EventQueueManager eventQueueManager;
|
private EventQueueManager eventQueueManager;
|
||||||
public Thread EventQueueThread;
|
public Thread EventQueueThread;
|
||||||
private static int ThreadCount = 0;
|
private static int ThreadCount = 0;
|
||||||
|
private ThreadPriority MyThreadPriority;
|
||||||
|
|
||||||
public EventQueueThreadClass(EventQueueManager eqm)
|
public EventQueueThreadClass(EventQueueManager eqm)
|
||||||
{
|
{
|
||||||
|
@ -43,9 +45,36 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void Start()
|
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 = new Thread(EventQueueThreadLoop);
|
||||||
EventQueueThread.IsBackground = true;
|
EventQueueThread.IsBackground = true;
|
||||||
EventQueueThread.Priority = ThreadPriority.BelowNormal;
|
|
||||||
|
EventQueueThread.Priority = MyThreadPriority;
|
||||||
EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount;
|
EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount;
|
||||||
EventQueueThread.Start();
|
EventQueueThread.Start();
|
||||||
|
|
||||||
|
@ -134,6 +163,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
+ ", QIS.functionName: " + QIS.functionName);
|
+ ", QIS.functionName: " + QIS.functionName);
|
||||||
#endif
|
#endif
|
||||||
LastExecutionStarted = DateTime.Now;
|
LastExecutionStarted = DateTime.Now;
|
||||||
|
KillCurrentScript = false;
|
||||||
InExecution = true;
|
InExecution = true;
|
||||||
eventQueueManager.m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, QIS.itemID,
|
eventQueueManager.m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, QIS.itemID,
|
||||||
QIS.functionName, QIS.llDetectParams, QIS.param);
|
QIS.functionName, QIS.llDetectParams, QIS.param);
|
||||||
|
@ -155,6 +185,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
// Send normal
|
// Send normal
|
||||||
text += e.Message.ToString();
|
text += e.Message.ToString();
|
||||||
}
|
}
|
||||||
|
if (KillCurrentScript)
|
||||||
|
text += "\r\nScript will be deactivated!";
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (text.Length > 1500)
|
if (text.Length > 1500)
|
||||||
|
@ -174,6 +207,14 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngine",
|
eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngine",
|
||||||
"Unable to send text in-world:\r\n" + text);
|
"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
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
@ -127,13 +127,17 @@ shout_distance = 100
|
||||||
; Threads are shared across all regions
|
; Threads are shared across all regions
|
||||||
NumberOfScriptThreads=2
|
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?
|
; Should the script threads be private for each region?
|
||||||
; true: Each region will get <NumberOfScriptThreads> dedicated to scripts within that region
|
; true: Each region will get <NumberOfScriptThreads> dedicated to scripts within that region
|
||||||
; Number of threads will be <NumberOfScriptThreads>*<NumberOfRegions>
|
; Number of threads will be <NumberOfScriptThreads>*<NumberOfRegions>
|
||||||
; false: All regions share <NumberOfScriptThreads> for all their scripts
|
; false: All regions share <NumberOfScriptThreads> for all their scripts
|
||||||
PrivateRegionThreads=false
|
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
|
; 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
|
; There is also a small speed penalty for every kill that is made
|
||||||
MaxEventExecutionTimeMs=5000
|
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?
|
; Should we enable the max script event execution thread to look for scripts that exceed their timeslice?
|
||||||
EnforceMaxEventExecutionTime=true
|
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
|
; If no scripts have executed in this pass how long should we sleep before checking again
|
||||||
; Impact:
|
; Impact:
|
||||||
; Too low and you will waste lots of CPU
|
; Too low and you will waste lots of CPU
|
||||||
|
|
Loading…
Reference in New Issue