aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs43
-rw-r--r--bin/OpenSim.ini.example11
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
128NumberOfScriptThreads=2 128NumberOfScriptThreads=2
129 129
130; Script event execution thread priority inside application.
131; Valid values: Lowest, BelowNormal, Normal, AboveNormal, Highest
132ScriptThreadPriority=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
134PrivateRegionThreads=false 138PrivateRegionThreads=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
139MaxEventExecutionTimeMs=5000 143MaxEventExecutionTimeMs=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?
142EnforceMaxEventExecutionTime=true 146EnforceMaxEventExecutionTime=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
151DeactivateScriptOnTimeout=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