diff options
author | Tedd Hansen | 2008-02-01 20:45:15 +0000 |
---|---|---|
committer | Tedd Hansen | 2008-02-01 20:45:15 +0000 |
commit | e14c8f59f7205ac010ed13387950647e5023b335 (patch) | |
tree | 2a4be137508c4114c289d960926f95c732c8110e | |
parent | Removed "Loading inventory for Primitive" message. (diff) | |
download | opensim-SC-e14c8f59f7205ac010ed13387950647e5023b335.zip opensim-SC-e14c8f59f7205ac010ed13387950647e5023b335.tar.gz opensim-SC-e14c8f59f7205ac010ed13387950647e5023b335.tar.bz2 opensim-SC-e14c8f59f7205ac010ed13387950647e5023b335.tar.xz |
Added config options:
ScriptThreadPriority to set script thread priority
DeactivateScriptOnTimeout to remove script if it is executing too long
3 files changed, 56 insertions, 3 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs index 6b2db35..d5826b7 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs | |||
@@ -82,11 +82,13 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
82 | /// </summary> | 82 | /// </summary> |
83 | private int numberOfThreads; | 83 | private int numberOfThreads; |
84 | 84 | ||
85 | |||
85 | /// <summary> | 86 | /// <summary> |
86 | /// Maximum time one function can use for execution before we perform a thread kill | 87 | /// Maximum time one function can use for execution before we perform a thread kill |
87 | /// </summary> | 88 | /// </summary> |
88 | private int maxFunctionExecutionTimems; | 89 | private int maxFunctionExecutionTimems; |
89 | private bool EnforceMaxExecutionTime; | 90 | private bool EnforceMaxExecutionTime; |
91 | private bool KillScriptOnMaxFunctionExecutionTime; | ||
90 | 92 | ||
91 | 93 | ||
92 | /// <summary> | 94 | /// <summary> |
@@ -169,7 +171,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
169 | 171 | ||
170 | maxFunctionExecutionTimems = m_ScriptEngine.ScriptConfigSource.GetInt("MaxEventExecutionTimeMs", 5000); | 172 | maxFunctionExecutionTimems = m_ScriptEngine.ScriptConfigSource.GetInt("MaxEventExecutionTimeMs", 5000); |
171 | EnforceMaxExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("EnforceMaxEventExecutionTime", false); | 173 | EnforceMaxExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("EnforceMaxEventExecutionTime", false); |
172 | 174 | KillScriptOnMaxFunctionExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("DeactivateScriptOnTimeout", false); | |
173 | 175 | ||
174 | 176 | ||
175 | // Start function max exec time enforcement thread | 177 | // Start function max exec time enforcement thread |
@@ -336,6 +338,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
336 | maxFunctionExecutionTimems) | 338 | maxFunctionExecutionTimems) |
337 | { | 339 | { |
338 | // We need to kill this thread! | 340 | // We need to kill this thread! |
341 | EventQueueThread.KillCurrentScript = KillScriptOnMaxFunctionExecutionTime; | ||
339 | AbortThreadClass(EventQueueThread); | 342 | AbortThreadClass(EventQueueThread); |
340 | // Then start another | 343 | // Then start another |
341 | StartNewThreadClass(); | 344 | StartNewThreadClass(); |
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs index 67cf0e2..57caad5 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs | |||
@@ -21,10 +21,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
21 | 21 | ||
22 | public DateTime LastExecutionStarted; | 22 | public DateTime LastExecutionStarted; |
23 | public bool InExecution = false; | 23 | public bool InExecution = false; |
24 | public bool KillCurrentScript = false; | ||
24 | 25 | ||
25 | private EventQueueManager eventQueueManager; | 26 | private EventQueueManager eventQueueManager; |
26 | public Thread EventQueueThread; | 27 | public Thread EventQueueThread; |
27 | private static int ThreadCount = 0; | 28 | private static int ThreadCount = 0; |
29 | private ThreadPriority MyThreadPriority; | ||
28 | 30 | ||
29 | public EventQueueThreadClass(EventQueueManager eqm) | 31 | public EventQueueThreadClass(EventQueueManager eqm) |
30 | { | 32 | { |
@@ -43,9 +45,36 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
43 | /// </summary> | 45 | /// </summary> |
44 | private void Start() | 46 | private void Start() |
45 | { | 47 | { |
48 | // Later with ScriptServer we might want to ask OS for stuff too, so doing this a bit manually | ||
49 | string pri = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetString("ScriptThreadPriority", "BelowNormal"); | ||
50 | switch (pri.ToLower()) | ||
51 | { | ||
52 | case "lowest": | ||
53 | MyThreadPriority = ThreadPriority.Lowest; | ||
54 | break; | ||
55 | case "belownormal": | ||
56 | MyThreadPriority = ThreadPriority.BelowNormal; | ||
57 | break; | ||
58 | case "normal": | ||
59 | MyThreadPriority = ThreadPriority.Normal; | ||
60 | break; | ||
61 | case "abovenormal": | ||
62 | MyThreadPriority = ThreadPriority.AboveNormal; | ||
63 | break; | ||
64 | case "highest": | ||
65 | MyThreadPriority = ThreadPriority.Highest; | ||
66 | break; | ||
67 | default: | ||
68 | MyThreadPriority = ThreadPriority.BelowNormal; // Default | ||
69 | eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngineBase", "Unknown priority type \"" + pri + "\" in config file. Defaulting to \"BelowNormal\"."); | ||
70 | break; | ||
71 | } | ||
72 | |||
73 | |||
46 | EventQueueThread = new Thread(EventQueueThreadLoop); | 74 | EventQueueThread = new Thread(EventQueueThreadLoop); |
47 | EventQueueThread.IsBackground = true; | 75 | EventQueueThread.IsBackground = true; |
48 | EventQueueThread.Priority = ThreadPriority.BelowNormal; | 76 | |
77 | EventQueueThread.Priority = MyThreadPriority; | ||
49 | EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount; | 78 | EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount; |
50 | EventQueueThread.Start(); | 79 | EventQueueThread.Start(); |
51 | 80 | ||
@@ -134,6 +163,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
134 | + ", QIS.functionName: " + QIS.functionName); | 163 | + ", QIS.functionName: " + QIS.functionName); |
135 | #endif | 164 | #endif |
136 | LastExecutionStarted = DateTime.Now; | 165 | LastExecutionStarted = DateTime.Now; |
166 | KillCurrentScript = false; | ||
137 | InExecution = true; | 167 | InExecution = true; |
138 | eventQueueManager.m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, QIS.itemID, | 168 | eventQueueManager.m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, QIS.itemID, |
139 | QIS.functionName, QIS.llDetectParams, QIS.param); | 169 | QIS.functionName, QIS.llDetectParams, QIS.param); |
@@ -155,6 +185,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
155 | // Send normal | 185 | // Send normal |
156 | text += e.Message.ToString(); | 186 | text += e.Message.ToString(); |
157 | } | 187 | } |
188 | if (KillCurrentScript) | ||
189 | text += "\r\nScript will be deactivated!"; | ||
190 | |||
158 | try | 191 | try |
159 | { | 192 | { |
160 | if (text.Length > 1500) | 193 | if (text.Length > 1500) |
@@ -174,6 +207,14 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | |||
174 | eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngine", | 207 | eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngine", |
175 | "Unable to send text in-world:\r\n" + text); | 208 | "Unable to send text in-world:\r\n" + text); |
176 | } | 209 | } |
210 | finally | ||
211 | { | ||
212 | // So we are done sending message in-world | ||
213 | if (KillCurrentScript) | ||
214 | { | ||
215 | eventQueueManager.m_ScriptEngine.m_ScriptManager.RemoveScript(QIS.localID, QIS.itemID); | ||
216 | } | ||
217 | } | ||
177 | } | 218 | } |
178 | finally | 219 | finally |
179 | { | 220 | { |
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index a0ada5c..3169cd0 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example | |||
@@ -127,13 +127,17 @@ shout_distance = 100 | |||
127 | ; Threads are shared across all regions | 127 | ; Threads are shared across all regions |
128 | NumberOfScriptThreads=2 | 128 | NumberOfScriptThreads=2 |
129 | 129 | ||
130 | ; Script event execution thread priority inside application. | ||
131 | ; Valid values: Lowest, BelowNormal, Normal, AboveNormal, Highest | ||
132 | ScriptThreadPriority=BelowNormal | ||
133 | |||
130 | ; Should the script threads be private for each region? | 134 | ; Should the script threads be private for each region? |
131 | ; true: Each region will get <NumberOfScriptThreads> dedicated to scripts within that region | 135 | ; true: Each region will get <NumberOfScriptThreads> dedicated to scripts within that region |
132 | ; Number of threads will be <NumberOfScriptThreads>*<NumberOfRegions> | 136 | ; Number of threads will be <NumberOfScriptThreads>*<NumberOfRegions> |
133 | ; false: All regions share <NumberOfScriptThreads> for all their scripts | 137 | ; false: All regions share <NumberOfScriptThreads> for all their scripts |
134 | PrivateRegionThreads=false | 138 | PrivateRegionThreads=false |
135 | 139 | ||
136 | ; How long MAX should a script be allowed to run? | 140 | ; How long MAX should a script event be allowed to run (per event execution)? |
137 | ; Do not set this too low (like 50ms) as there are some time wasted in simply executing a function | 141 | ; Do not set this too low (like 50ms) as there are some time wasted in simply executing a function |
138 | ; There is also a small speed penalty for every kill that is made | 142 | ; There is also a small speed penalty for every kill that is made |
139 | MaxEventExecutionTimeMs=5000 | 143 | MaxEventExecutionTimeMs=5000 |
@@ -141,6 +145,11 @@ MaxEventExecutionTimeMs=5000 | |||
141 | ; Should we enable the max script event execution thread to look for scripts that exceed their timeslice? | 145 | ; Should we enable the max script event execution thread to look for scripts that exceed their timeslice? |
142 | EnforceMaxEventExecutionTime=true | 146 | EnforceMaxEventExecutionTime=true |
143 | 147 | ||
148 | ; Should we stop the script completely when time exceeds? | ||
149 | ; This is useful if you have a high <MaxEventExecutionTimeMs> and want to deactivate scripts that go wrong | ||
150 | ; Note that for example physics engine can slow down the system and make scripts spend more time | ||
151 | DeactivateScriptOnTimeout=false | ||
152 | |||
144 | ; If no scripts have executed in this pass how long should we sleep before checking again | 153 | ; If no scripts have executed in this pass how long should we sleep before checking again |
145 | ; Impact: | 154 | ; Impact: |
146 | ; Too low and you will waste lots of CPU | 155 | ; Too low and you will waste lots of CPU |