diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs | 328 |
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> |