aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs328
1 files changed, 167 insertions, 161 deletions
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>