aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorTedd Hansen2008-02-22 22:24:12 +0000
committerTedd Hansen2008-02-22 22:24:12 +0000
commitf06a6573bb94d1a61ddabd1289d0ea541f7788c1 (patch)
tree87b5a5b08507e5594ccd786b1c002d4e985f5d10
parent* Converted the last of the events to the private delegate instance method to... (diff)
downloadopensim-SC_OLD-f06a6573bb94d1a61ddabd1289d0ea541f7788c1.zip
opensim-SC_OLD-f06a6573bb94d1a61ddabd1289d0ea541f7788c1.tar.gz
opensim-SC_OLD-f06a6573bb94d1a61ddabd1289d0ea541f7788c1.tar.bz2
opensim-SC_OLD-f06a6573bb94d1a61ddabd1289d0ea541f7788c1.tar.xz
One more: Async LSL command thread is also shared now.
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs81
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs328
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs86
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs28
-rw-r--r--bin/OpenSim.ini.example10
5 files changed, 279 insertions, 254 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
index fbdfff8..556593d 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
@@ -41,28 +41,36 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
41 /// </summary> 41 /// </summary>
42 public class AsyncLSLCommandManager : iScriptEngineFunctionModule 42 public class AsyncLSLCommandManager : iScriptEngineFunctionModule
43 { 43 {
44 private Thread cmdHandlerThread; 44 private static Thread cmdHandlerThread;
45 private int cmdHandlerThreadCycleSleepms; 45 private int cmdHandlerThreadCycleSleepms;
46 46
47 private ScriptEngine m_ScriptEngine; 47 private ScriptEngine m_ScriptEngine;
48 48
49 public AsyncLSLCommandManager(ScriptEngine _ScriptEngine) 49 public AsyncLSLCommandManager()
50 { 50 {
51 m_ScriptEngine = _ScriptEngine; 51 //m_ScriptEngine = _ScriptEngine;
52 ReadConfig(); 52 ReadConfig();
53 53
54 // Start the thread that will be doing the work 54 StartThread();
55 cmdHandlerThread = new Thread(CmdHandlerThreadLoop); 55 }
56 cmdHandlerThread.Name = "CmdHandlerThread"; 56
57 cmdHandlerThread.Priority = ThreadPriority.BelowNormal; 57 private void StartThread()
58 cmdHandlerThread.IsBackground = true; 58 {
59 cmdHandlerThread.Start(); 59 if (cmdHandlerThread == null)
60 OpenSim.Framework.ThreadTracker.Add(cmdHandlerThread); 60 {
61 // Start the thread that will be doing the work
62 cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
63 cmdHandlerThread.Name = "AsyncLSLCmdHandlerThread";
64 cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
65 cmdHandlerThread.IsBackground = true;
66 cmdHandlerThread.Start();
67 OpenSim.Framework.ThreadTracker.Add(cmdHandlerThread);
68 }
61 } 69 }
62 70
63 public void ReadConfig() 71 public void ReadConfig()
64 { 72 {
65 cmdHandlerThreadCycleSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("AsyncLLCommandLoopms", 50); 73 cmdHandlerThreadCycleSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("AsyncLLCommandLoopms", 100);
66 } 74 }
67 75
68 ~AsyncLSLCommandManager() 76 ~AsyncLSLCommandManager()
@@ -88,29 +96,46 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
88 { 96 {
89 while (true) 97 while (true)
90 { 98 {
91 // Check timers 99 try
92 CheckTimerEvents(); 100 {
93 Thread.Sleep(25); 101 while (true)
94 // Check HttpRequests 102 {
95 CheckHttpRequests(); 103 Thread.Sleep(cmdHandlerThreadCycleSleepms);
96 Thread.Sleep(25); 104 lock (ScriptEngine.ScriptEngines)
97 // Check XMLRPCRequests 105 {
98 CheckXMLRPCRequests(); 106 foreach (ScriptEngine se in ScriptEngine.ScriptEngines)
99 Thread.Sleep(25); 107 {
100 // Check Listeners 108 m_ScriptEngine = se;
101 CheckListeners(); 109 m_ScriptEngine.m_ASYNCLSLCommandManager.DoOneCmdHandlerPass();
102 Thread.Sleep(25); 110 }
103 111 }
104 // Sleep before next cycle 112 // Sleep before next cycle
105 //Thread.Sleep(cmdHandlerThreadCycleSleepms); 113 //Thread.Sleep(cmdHandlerThreadCycleSleepms);
114 }
115 }
116 catch
117 {
118 }
106 } 119 }
107 } 120 }
108 121
122 internal void DoOneCmdHandlerPass()
123 {
124 // Check timers
125 CheckTimerEvents();
126 // Check HttpRequests
127 CheckHttpRequests();
128 // Check XMLRPCRequests
129 CheckXMLRPCRequests();
130 // Check Listeners
131 CheckListeners();
132 }
133
109 /// <summary> 134 /// <summary>
110 /// Remove a specific script (and all its pending commands) 135 /// Remove a specific script (and all its pending commands)
111 /// </summary> 136 /// </summary>
112 /// <param name="m_localID"></param> 137 /// <param name="localID"></param>
113 /// <param name="m_itemID"></param> 138 /// <param name="itemID"></param>
114 public void RemoveScript(uint localID, LLUUID itemID) 139 public void RemoveScript(uint localID, LLUUID itemID)
115 { 140 {
116 // Remove a specific script 141 // Remove a specific script
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
index c0edcc4..a70e93b 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
@@ -73,38 +73,40 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
73 73
74 public void ReadConfig() 74 public void ReadConfig()
75 { 75 {
76 foreach (ScriptEngine m_ScriptEngine in new ArrayList(ScriptEngine.ScriptEngines)) 76 //lock (ScriptEngine.ScriptEngines)
77 { 77 //{
78 ScriptEngineName = m_ScriptEngine.ScriptEngineName; 78 foreach (ScriptEngine m_ScriptEngine in new ArrayList(ScriptEngine.ScriptEngines))
79 nothingToDoSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("SleepTimeIfNoScriptExecutionMs", 50);
80
81 // Later with ScriptServer we might want to ask OS for stuff too, so doing this a bit manually
82 string pri = m_ScriptEngine.ScriptConfigSource.GetString("ScriptThreadPriority", "BelowNormal");
83 switch (pri.ToLower())
84 { 79 {
85 case "lowest": 80 ScriptEngineName = m_ScriptEngine.ScriptEngineName;
86 MyThreadPriority = ThreadPriority.Lowest; 81 nothingToDoSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("SleepTimeIfNoScriptExecutionMs", 50);
87 break;
88 case "belownormal":
89 MyThreadPriority = ThreadPriority.BelowNormal;
90 break;
91 case "normal":
92 MyThreadPriority = ThreadPriority.Normal;
93 break;
94 case "abovenormal":
95 MyThreadPriority = ThreadPriority.AboveNormal;
96 break;
97 case "highest":
98 MyThreadPriority = ThreadPriority.Highest;
99 break;
100 default:
101 MyThreadPriority = ThreadPriority.BelowNormal; // Default
102 m_ScriptEngine.Log.Error("[ScriptEngineBase]: Unknown priority type \"" + pri +
103 "\" in config file. Defaulting to \"BelowNormal\".");
104 break;
105 }
106 }
107 82
83 // Later with ScriptServer we might want to ask OS for stuff too, so doing this a bit manually
84 string pri = m_ScriptEngine.ScriptConfigSource.GetString("ScriptThreadPriority", "BelowNormal");
85 switch (pri.ToLower())
86 {
87 case "lowest":
88 MyThreadPriority = ThreadPriority.Lowest;
89 break;
90 case "belownormal":
91 MyThreadPriority = ThreadPriority.BelowNormal;
92 break;
93 case "normal":
94 MyThreadPriority = ThreadPriority.Normal;
95 break;
96 case "abovenormal":
97 MyThreadPriority = ThreadPriority.AboveNormal;
98 break;
99 case "highest":
100 MyThreadPriority = ThreadPriority.Highest;
101 break;
102 default:
103 MyThreadPriority = ThreadPriority.BelowNormal; // Default
104 m_ScriptEngine.Log.Error("[ScriptEngineBase]: Unknown priority type \"" + pri +
105 "\" in config file. Defaulting to \"BelowNormal\".");
106 break;
107 }
108 }
109 //}
108 // Now set that priority 110 // Now set that priority
109 if (EventQueueThread != null) 111 if (EventQueueThread != null)
110 if (EventQueueThread.IsAlive) 112 if (EventQueueThread.IsAlive)
@@ -187,159 +189,163 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
187 189
188 public void DoProcessQueue() 190 public void DoProcessQueue()
189 { 191 {
190 foreach (ScriptEngine m_ScriptEngine in new ArrayList(ScriptEngine.ScriptEngines)) 192 //lock (ScriptEngine.ScriptEngines)
191 { 193 //{
192 lastScriptEngine = m_ScriptEngine; 194 foreach (ScriptEngine m_ScriptEngine in new ArrayList(ScriptEngine.ScriptEngines))
193 // Every now and then check if we should shut down 195 {
194 //if (PleaseShutdown || EventQueueManager.ThreadsToExit > 0) 196 lastScriptEngine = m_ScriptEngine;
195 //{ 197 // Every now and then check if we should shut down
196 // // Someone should shut down, lets get exclusive lock 198 //if (PleaseShutdown || EventQueueManager.ThreadsToExit > 0)
197 // lock (EventQueueManager.ThreadsToExitLock) 199 //{
198 // { 200 // // Someone should shut down, lets get exclusive lock
199 // // Lets re-check in case someone grabbed it 201 // lock (EventQueueManager.ThreadsToExitLock)
200 // if (EventQueueManager.ThreadsToExit > 0) 202 // {
201 // { 203 // // Lets re-check in case someone grabbed it
202 // // Its crowded here so we'll shut down 204 // if (EventQueueManager.ThreadsToExit > 0)
203 // EventQueueManager.ThreadsToExit--; 205 // {
204 // Stop(); 206 // // Its crowded here so we'll shut down
205 // return; 207 // EventQueueManager.ThreadsToExit--;
206 // } 208 // Stop();
207 // else 209 // return;
208 // { 210 // }
209 // // We have been asked to shut down 211 // else
210 // Stop(); 212 // {
211 // return; 213 // // We have been asked to shut down
212 // } 214 // Stop();
213 // } 215 // return;
214 //} 216 // }
217 // }
218 //}
215 219
216 //try 220 //try
217 // { 221 // {
218 EventQueueManager.QueueItemStruct QIS = BlankQIS; 222 EventQueueManager.QueueItemStruct QIS = BlankQIS;
219 bool GotItem = false; 223 bool GotItem = false;
220 224
221 //if (PleaseShutdown) 225 //if (PleaseShutdown)
222 // return; 226 // return;
223 227
224 if (m_ScriptEngine.m_EventQueueManager.eventQueue.Count == 0) 228 if (m_ScriptEngine.m_EventQueueManager.eventQueue.Count == 0)
225 {
226 // Nothing to do? Sleep a bit waiting for something to do
227 Thread.Sleep(nothingToDoSleepms);
228 }
229 else
230 {
231 // Something in queue, process
232 //myScriptEngine.Log.Info("[" + ScriptEngineName + "]: Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName);
233
234 // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
235 lock (m_ScriptEngine.m_EventQueueManager.eventQueue)
236 { 229 {
237 GotItem = false; 230 // Nothing to do? Sleep a bit waiting for something to do
238 for (int qc = 0; qc < m_ScriptEngine.m_EventQueueManager.eventQueue.Count; qc++) 231 Thread.Sleep(nothingToDoSleepms);
239 { 232 }
240 // Get queue item 233 else
241 QIS = m_ScriptEngine.m_EventQueueManager.eventQueue.Dequeue(); 234 {
235 // Something in queue, process
236 //myScriptEngine.Log.Info("[" + ScriptEngineName + "]: Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName);
242 237
243 // Check if object is being processed by someone else 238 // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
244 if (m_ScriptEngine.m_EventQueueManager.TryLock(QIS.localID) == false) 239 lock (m_ScriptEngine.m_EventQueueManager.eventQueue)
245 { 240 {
246 // Object is already being processed, requeue it 241 GotItem = false;
247 m_ScriptEngine.m_EventQueueManager.eventQueue.Enqueue(QIS); 242 for (int qc = 0; qc < m_ScriptEngine.m_EventQueueManager.eventQueue.Count; qc++)
248 }
249 else
250 { 243 {
251 // We have lock on an object and can process it 244 // Get queue item
252 GotItem = true; 245 QIS = m_ScriptEngine.m_EventQueueManager.eventQueue.Dequeue();
253 break; 246
247 // Check if object is being processed by someone else
248 if (m_ScriptEngine.m_EventQueueManager.TryLock(QIS.localID) == false)
249 {
250 // Object is already being processed, requeue it
251 m_ScriptEngine.m_EventQueueManager.eventQueue.Enqueue(QIS);
252 }
253 else
254 {
255 // We have lock on an object and can process it
256 GotItem = true;
257 break;
258 }
254 } 259 }
255 } 260 }
256 }
257 261
258 if (GotItem == true) 262 if (GotItem == true)
259 {
260 // Execute function
261 try
262 { 263 {
263 ///cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined 264 // Execute function
265 try
266 {
267 ///cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined
264#if DEBUG 268#if DEBUG
265 //eventQueueManager.m_ScriptEngine.Log.Debug("[" + ScriptEngineName + "]: " + 269 //eventQueueManager.m_ScriptEngine.Log.Debug("[" + ScriptEngineName + "]: " +
266 // "Executing event:\r\n" 270 // "Executing event:\r\n"
267 // + "QIS.localID: " + QIS.localID 271 // + "QIS.localID: " + QIS.localID
268 // + ", QIS.itemID: " + QIS.itemID 272 // + ", QIS.itemID: " + QIS.itemID
269 // + ", QIS.functionName: " + 273 // + ", QIS.functionName: " +
270 // QIS.functionName); 274 // QIS.functionName);
271#endif 275#endif
272 LastExecutionStarted = DateTime.Now.Ticks; 276 LastExecutionStarted = DateTime.Now.Ticks;
273 KillCurrentScript = false; 277 KillCurrentScript = false;
274 InExecution = true; 278 InExecution = true;
275 m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, 279 m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID,
276 QIS.itemID, 280 QIS.itemID,
277 QIS.functionName, 281 QIS.functionName,
278 QIS.llDetectParams, 282 QIS.llDetectParams,
279 QIS.param); 283 QIS.param);
280 InExecution = false; 284 InExecution = false;
281 }
282 catch (Exception e)
283 {
284 InExecution = false;
285 // DISPLAY ERROR INWORLD
286 string text = "Error executing script function \"" + QIS.functionName +
287 "\":\r\n";
288 if (e.InnerException != null)
289 {
290 // Send inner exception
291 text += e.InnerException.Message.ToString();
292 } 285 }
293 else 286 catch (Exception e)
294 { 287 {
295 text += "\r\n"; 288 InExecution = false;
296 // Send normal 289 // DISPLAY ERROR INWORLD
297 text += e.Message.ToString(); 290 string text = "Error executing script function \"" + QIS.functionName +
298 } 291 "\":\r\n";
299 if (KillCurrentScript) 292 if (e.InnerException != null)
300 text += "\r\nScript will be deactivated!"; 293 {
294 // Send inner exception
295 text += e.InnerException.Message.ToString();
296 }
297 else
298 {
299 text += "\r\n";
300 // Send normal
301 text += e.Message.ToString();
302 }
303 if (KillCurrentScript)
304 text += "\r\nScript will be deactivated!";
301 305
302 try 306 try
303 { 307 {
304 if (text.Length > 1500) 308 if (text.Length > 1500)
305 text = text.Substring(0, 1500); 309 text = text.Substring(0, 1500);
306 IScriptHost m_host = 310 IScriptHost m_host =
307 m_ScriptEngine.World.GetSceneObjectPart(QIS.localID); 311 m_ScriptEngine.World.GetSceneObjectPart(QIS.localID);
308 //if (m_host != null) 312 //if (m_host != null)
309 //{ 313 //{
310 m_ScriptEngine.World.SimChat(Helpers.StringToField(text), 314 m_ScriptEngine.World.SimChat(Helpers.StringToField(text),
311 ChatTypeEnum.Say, 0, 315 ChatTypeEnum.Say, 0,
312 m_host.AbsolutePosition, 316 m_host.AbsolutePosition,
313 m_host.Name, m_host.UUID); 317 m_host.Name, m_host.UUID);
314 } 318 }
315 catch 319 catch
316 { 320 {
317 //} 321 //}
318 //else 322 //else
319 //{ 323 //{
320 // T oconsole 324 // T oconsole
321 m_ScriptEngine.m_EventQueueManager.m_ScriptEngine.Log.Error("[" + ScriptEngineName + "]: " + 325 m_ScriptEngine.m_EventQueueManager.m_ScriptEngine.Log.Error("[" + ScriptEngineName +
322 "Unable to send text in-world:\r\n" + 326 "]: " +
323 text); 327 "Unable to send text in-world:\r\n" +
328 text);
329 }
330 finally
331 {
332 // So we are done sending message in-world
333 if (KillCurrentScript)
334 {
335 m_ScriptEngine.m_EventQueueManager.m_ScriptEngine.m_ScriptManager.StopScript(
336 QIS.localID, QIS.itemID);
337 }
338 }
324 } 339 }
325 finally 340 finally
326 { 341 {
327 // So we are done sending message in-world 342 InExecution = false;
328 if (KillCurrentScript) 343 m_ScriptEngine.m_EventQueueManager.ReleaseLock(QIS.localID);
329 {
330 m_ScriptEngine.m_EventQueueManager.m_ScriptEngine.m_ScriptManager.StopScript(
331 QIS.localID, QIS.itemID);
332 }
333 } 344 }
334 } 345 }
335 finally
336 {
337 InExecution = false;
338 m_ScriptEngine.m_EventQueueManager.ReleaseLock(QIS.localID);
339 }
340 } 346 }
341 } 347 }
342 } 348 // }
343 } 349 }
344 350
345 ///// <summary> 351 ///// <summary>
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs
index e0ec27f..eb57a9e 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs
@@ -63,13 +63,18 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
63 public void ReadConfig() 63 public void ReadConfig()
64 { 64 {
65 // Bad hack, but we need a m_ScriptEngine :) 65 // Bad hack, but we need a m_ScriptEngine :)
66 foreach (ScriptEngine m_ScriptEngine in ScriptEngine.ScriptEngines) 66 lock (ScriptEngine.ScriptEngines)
67 { 67 {
68 MaintenanceLoopms = m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopms", 50); 68 foreach (ScriptEngine m_ScriptEngine in ScriptEngine.ScriptEngines)
69 MaintenanceLoopTicks_ScriptLoadUnload = m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopTicks_ScriptLoadUnload", 1); 69 {
70 MaintenanceLoopTicks_Other = m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopTicks_Other", 10); 70 MaintenanceLoopms = m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopms", 50);
71 MaintenanceLoopTicks_ScriptLoadUnload =
72 m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopTicks_ScriptLoadUnload", 1);
73 MaintenanceLoopTicks_Other =
74 m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopTicks_Other", 10);
71 75
72 return; 76 return;
77 }
73 } 78 }
74 } 79 }
75 80
@@ -159,52 +164,53 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
159 MaintenanceLoopTicks_Other_Count++; 164 MaintenanceLoopTicks_Other_Count++;
160 165
161 166
162 foreach (ScriptEngine m_ScriptEngine in new ArrayList(ScriptEngine.ScriptEngines)) 167 lock (ScriptEngine.ScriptEngines)
163 { 168 {
164 lastScriptEngine = m_ScriptEngine; 169 foreach (ScriptEngine m_ScriptEngine in ScriptEngine.ScriptEngines)
165 // Re-reading config every x seconds
166 if (MaintenanceLoopTicks_Other_Count >= MaintenanceLoopTicks_Other)
167 { 170 {
168 MaintenanceLoopTicks_Other_ResetCount = true; 171 lastScriptEngine = m_ScriptEngine;
169 if (m_ScriptEngine.RefreshConfigFilens > 0) 172 // Re-reading config every x seconds
173 if (MaintenanceLoopTicks_Other_Count >= MaintenanceLoopTicks_Other)
170 { 174 {
171 175 MaintenanceLoopTicks_Other_ResetCount = true;
172 // Check if its time to re-read config 176 if (m_ScriptEngine.RefreshConfigFilens > 0)
173 if (DateTime.Now.Ticks - Last_ReReadConfigFilens >
174 m_ScriptEngine.RefreshConfigFilens)
175 { 177 {
176 //Console.WriteLine("Time passed: " + (DateTime.Now.Ticks - Last_ReReadConfigFilens) + ">" + m_ScriptEngine.RefreshConfigFilens ); 178 // Check if its time to re-read config
177 // Its time to re-read config file 179 if (DateTime.Now.Ticks - Last_ReReadConfigFilens >
178 m_ScriptEngine.ReadConfig(); 180 m_ScriptEngine.RefreshConfigFilens)
179 Last_ReReadConfigFilens = DateTime.Now.Ticks; // Reset time 181 {
180 } 182 //Console.WriteLine("Time passed: " + (DateTime.Now.Ticks - Last_ReReadConfigFilens) + ">" + m_ScriptEngine.RefreshConfigFilens );
183 // Its time to re-read config file
184 m_ScriptEngine.ReadConfig();
185 Last_ReReadConfigFilens = DateTime.Now.Ticks; // Reset time
186 }
181 187
182 188
183 // Adjust number of running script threads if not correct 189 // Adjust number of running script threads if not correct
184 if (m_ScriptEngine.m_EventQueueManager != null) 190 if (m_ScriptEngine.m_EventQueueManager != null)
185 m_ScriptEngine.m_EventQueueManager.AdjustNumberOfScriptThreads(); 191 m_ScriptEngine.m_EventQueueManager.AdjustNumberOfScriptThreads();
186 192
187 // Check if any script has exceeded its max execution time 193 // Check if any script has exceeded its max execution time
188 if (EventQueueManager.EnforceMaxExecutionTime) 194 if (EventQueueManager.EnforceMaxExecutionTime)
189 {
190 // We are enforcing execution time
191 if (DateTime.Now.Ticks - Last_maxFunctionExecutionTimens >
192 EventQueueManager.maxFunctionExecutionTimens)
193 { 195 {
194 // Its time to check again 196 // We are enforcing execution time
195 m_ScriptEngine.m_EventQueueManager.CheckScriptMaxExecTime(); // Do check 197 if (DateTime.Now.Ticks - Last_maxFunctionExecutionTimens >
196 Last_maxFunctionExecutionTimens = DateTime.Now.Ticks; // Reset time 198 EventQueueManager.maxFunctionExecutionTimens)
199 {
200 // Its time to check again
201 m_ScriptEngine.m_EventQueueManager.CheckScriptMaxExecTime(); // Do check
202 Last_maxFunctionExecutionTimens = DateTime.Now.Ticks; // Reset time
203 }
197 } 204 }
198 } 205 }
199 } 206 }
200 207 if (MaintenanceLoopTicks_ScriptLoadUnload_Count >= MaintenanceLoopTicks_ScriptLoadUnload)
201 } 208 {
202 if (MaintenanceLoopTicks_ScriptLoadUnload_Count >= MaintenanceLoopTicks_ScriptLoadUnload) 209 MaintenanceLoopTicks_ScriptLoadUnload_ResetCount = true;
203 { 210 // LOAD / UNLOAD SCRIPTS
204 MaintenanceLoopTicks_ScriptLoadUnload_ResetCount = true; 211 if (m_ScriptEngine.m_ScriptManager != null)
205 // LOAD / UNLOAD SCRIPTS 212 m_ScriptEngine.m_ScriptManager.DoScriptLoadUnload();
206 if (m_ScriptEngine.m_ScriptManager != null) 213 }
207 m_ScriptEngine.m_ScriptManager.DoScriptLoadUnload();
208 } 214 }
209 } 215 }
210 } 216 }
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
index 60416eb..b861ad5 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
@@ -84,7 +84,10 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
84 public ScriptEngine() 84 public ScriptEngine()
85 { 85 {
86 Common.mySE = this; // For logging, just need any instance, doesn't matter 86 Common.mySE = this; // For logging, just need any instance, doesn't matter
87 ScriptEngines.Add(this); // Keep a list of ScriptEngines for shared threads to process all instances 87 lock (ScriptEngines)
88 {
89 ScriptEngines.Add(this); // Keep a list of ScriptEngines for shared threads to process all instances
90 }
88 } 91 }
89 92
90 public void InitializeEngine(Scene Sceneworld, IConfigSource config, bool HookUpToServer, ScriptManager newScriptManager) 93 public void InitializeEngine(Scene Sceneworld, IConfigSource config, bool HookUpToServer, ScriptManager newScriptManager)
@@ -107,7 +110,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
107 newScriptManager.Start(); 110 newScriptManager.Start();
108 m_ScriptManager = newScriptManager; 111 m_ScriptManager = newScriptManager;
109 m_AppDomainManager = new AppDomainManager(this); 112 m_AppDomainManager = new AppDomainManager(this);
110 m_ASYNCLSLCommandManager = new AsyncLSLCommandManager(this); 113 m_ASYNCLSLCommandManager = new AsyncLSLCommandManager();
111 if (m_MaintenanceThread == null) 114 if (m_MaintenanceThread == null)
112 m_MaintenanceThread = new MaintenanceThread(); 115 m_MaintenanceThread = new MaintenanceThread();
113 116
@@ -121,7 +124,10 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
121 public void Shutdown() 124 public void Shutdown()
122 { 125 {
123 // We are shutting down 126 // We are shutting down
124 ScriptEngines.Remove(this); 127 lock (ScriptEngines)
128 {
129 ScriptEngines.Remove(this);
130 }
125 } 131 }
126 132
127 ScriptServerInterfaces.RemoteEvents ScriptServerInterfaces.ScriptEngine.EventManager() 133 ScriptServerInterfaces.RemoteEvents ScriptServerInterfaces.ScriptEngine.EventManager()
@@ -136,13 +142,6 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
136#endif 142#endif
137 RefreshConfigFileSeconds = ScriptConfigSource.GetInt("RefreshConfig", 30); 143 RefreshConfigFileSeconds = ScriptConfigSource.GetInt("RefreshConfig", 30);
138 144
139 // Reload from disk? No!
140 //ConfigSource.Reload();
141 //if (File.Exists(OpenSim.Application.iniFilePath))
142 //{
143 // //ConfigSource.Merge(new IniConfigSource(OpenSim.Application.iniFilePath));
144 //}
145
146 145
147 // Create a new object (probably not necessary?) 146 // Create a new object (probably not necessary?)
148// ScriptConfigSource = ConfigSource.Configs[ScriptEngineName]; 147// ScriptConfigSource = ConfigSource.Configs[ScriptEngineName];
@@ -179,15 +178,6 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
179 178
180 #endregion 179 #endregion
181 180
182 /// <summary>
183 /// If set to true then threads and stuff should try to make a graceful exit
184 /// </summary>
185 //public bool PleaseShutdown
186 //{
187 // get { return _PleaseShutdown; }
188 // set { _PleaseShutdown = value; }
189 //}
190 //private bool _PleaseShutdown = false;
191 181
192 } 182 }
193} 183}
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 793fe5b..084d9f7 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -210,12 +210,6 @@ SleepTimeIfNoScriptExecutionMs=50
210; Each AppDomain has some memory overhead. But leaving dead scripts in memory also has memory overhead. 210; Each AppDomain has some memory overhead. But leaving dead scripts in memory also has memory overhead.
211ScriptsPerAppDomain=1 211ScriptsPerAppDomain=1
212 212
213; Script loading / unloading sleep
214; How long load/unload thread should sleep if there is nothing to do
215; Higher value makes it respond slower when scripts are added/removed from prims
216; But once active it will process all in queue before sleeping again
217
218
219; MaintenanceLoop 213; MaintenanceLoop
220; How often to run maintenance loop 214; How often to run maintenance loop
221; Maintenance loop is doing: script compile/load, script unload, reload config, adjust running config and enforce max execution time 215; Maintenance loop is doing: script compile/load, script unload, reload config, adjust running config and enforce max execution time
@@ -224,6 +218,10 @@ MaintenanceLoopms=50
224; How many maintenanceloops between each of these. 218; How many maintenanceloops between each of these.
225; (if 2 then function will be executed every MaintenanceLoopms*2 ms) 219; (if 2 then function will be executed every MaintenanceLoopms*2 ms)
226; Script loading/unloading 220; Script loading/unloading
221
222; How long load/unload thread should sleep if there is nothing to do
223; Higher value makes it respond slower when scripts are added/removed from prims
224; But once active it will process all in queue before sleeping again
227MaintenanceLoopTicks_ScriptLoadUnload=1 225MaintenanceLoopTicks_ScriptLoadUnload=1
228 226
229; Other tasks 227; Other tasks