diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 17c06e74a8..9ff2e4dd67 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -139,7 +139,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance set { m_RunEvents = value; } } - public bool Suspended { get; set; } + public bool Suspended + { + get { return m_Suspended; } + + set + { + // Need to do this inside a lock in order to avoid races with EventProcessor() + lock (m_Script) + { + bool wasSuspended = m_Suspended; + m_Suspended = value; + + if (wasSuspended && !m_Suspended) + { + lock (m_EventQueue) + { + // Need to place ourselves back in a work item if there are events to process + if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) + m_CurrentResult = m_Engine.QueueEventHandler(this); + } + } + } + } + } + private bool m_Suspended; public bool ShuttingDown { @@ -650,38 +674,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance { EventParams data = null; +// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); + if (Suspended) return 0; lock (m_EventQueue) { - lock (m_Script) + data = (EventParams) m_EventQueue.Dequeue(); + if (data == null) // Shouldn't happen { - data = (EventParams) m_EventQueue.Dequeue(); - if (data == null) // Shouldn't happen + if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) { - if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) - { - m_CurrentResult = m_Engine.QueueEventHandler(this); - } - else - { - m_CurrentResult = null; - } - return 0; + m_CurrentResult = m_Engine.QueueEventHandler(this); } - - if (data.EventName == "timer") - m_TimerQueued = false; - if (data.EventName == "control") + else { - if (m_ControlEventsInQueue > 0) - m_ControlEventsInQueue--; + m_CurrentResult = null; } - if (data.EventName == "collision") - m_CollisionInQueue = false; + return 0; } + + if (data.EventName == "timer") + m_TimerQueued = false; + if (data.EventName == "control") + { + if (m_ControlEventsInQueue > 0) + m_ControlEventsInQueue--; + } + if (data.EventName == "collision") + m_CollisionInQueue = false; } + lock(m_Script) { @@ -693,7 +717,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance { // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}", // m_PrimName, m_ScriptName, data.Params[0].ToString()); - m_State=data.Params[0].ToString(); + m_State = data.Params[0].ToString(); AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 696c216a90..aa11ecabdd 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1009,7 +1009,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine // Do we even have it? if (!m_Scripts.ContainsKey(itemID)) { + // Do we even have it? + if (!m_Scripts.ContainsKey(itemID)) + return; + lockScriptsForRead(false); + lockScriptsForWrite(true); + m_Scripts.Remove(itemID); + lockScriptsForWrite(false); + return; }