From 25e200c46a7664eb23499c39e6a1019470e26edc Mon Sep 17 00:00:00 2001 From: Tedd Hansen Date: Sun, 26 Aug 2007 08:20:48 +0000 Subject: [PATCH] Fixed bug that occurs sometimes on script unload where queued script event was attempted executed after AppDomain was unloaded. --- .../DotNetEngine/EventQueueManager.cs | 99 ++++++++++--------- .../DotNetEngine/ScriptManager.cs | 11 ++- 2 files changed, 63 insertions(+), 47 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs index 99971a5a6a..9037c2ae8e 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs @@ -131,57 +131,64 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine QueueItemStruct BlankQIS = new QueueItemStruct(); while (true) { - QueueItemStruct QIS = BlankQIS; - bool GotItem = false; - - if (EventQueue.Count == 0) + try { - // Nothing to do? Sleep a bit waiting for something to do - Thread.Sleep(NothingToDoSleepms); - } - else - { - // Something in queue, process - //myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName); + QueueItemStruct QIS = BlankQIS; + bool GotItem = false; - // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD - lock (QueueLock) + if (EventQueue.Count == 0) { - GotItem = false; - for (int qc = 0; qc < EventQueue.Count; qc++) - { - // Get queue item - QIS = EventQueue.Dequeue(); - - // Check if object is being processed by someone else - if (TryLock(QIS.localID) == false) - { - // Object is already being processed, requeue it - EventQueue.Enqueue(QIS); - } - else - { - // We have lock on an object and can process it - GotItem = true; - break; - } - } // go through queue - } // lock - - if (GotItem == true) - { - // Execute function - try - { - myScriptEngine.myScriptManager.ExecuteEvent(QIS.localID, QIS.itemID, QIS.FunctionName, QIS.param); - } - finally - { - ReleaseLock(QIS.localID); - } + // Nothing to do? Sleep a bit waiting for something to do + Thread.Sleep(NothingToDoSleepms); } + else + { + // Something in queue, process + //myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName); - } // Something in queue + // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD + lock (QueueLock) + { + GotItem = false; + for (int qc = 0; qc < EventQueue.Count; qc++) + { + // Get queue item + QIS = EventQueue.Dequeue(); + + // Check if object is being processed by someone else + if (TryLock(QIS.localID) == false) + { + // Object is already being processed, requeue it + EventQueue.Enqueue(QIS); + } + else + { + // We have lock on an object and can process it + GotItem = true; + break; + } + } // go through queue + } // lock + + if (GotItem == true) + { + // Execute function + try + { + myScriptEngine.myScriptManager.ExecuteEvent(QIS.localID, QIS.itemID, QIS.FunctionName, QIS.param); + } + finally + { + ReleaseLock(QIS.localID); + } + } + + } // Something in queue + } catch {ThreadAbortException tae) { + throw tae; + } catch (Exception e) { + Console.WriteLine("Exception in EventQueueThreadLoop: " + e.ToString()); + } } // while } // try catch (ThreadAbortException tae) diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs index c7c33bb2ac..5dc928ade9 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs @@ -362,9 +362,18 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine // Execute a function in the script //m_scriptEngine.Log.Verbose("ScriptEngine", "Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName); LSL_BaseClass Script = m_scriptEngine.myScriptManager.GetScript(localID, itemID); + if (Script == null) + return; // Must be done in correct AppDomain, so leaving it up to the script itself - Script.Exec.ExecuteEvent(FunctionName, args); + try + { + Script.Exec.ExecuteEvent(FunctionName, args); + } + catch (Exception e) + { + Console.WriteLine("Exception executing script funcion: " + e.ToString()); + } }