diff options
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b8ff7f7..bab14dd 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -121,6 +121,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
121 | /// <remarks> | 121 | /// <remarks> |
122 | /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is | 122 | /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is |
123 | /// necessary. | 123 | /// necessary. |
124 | /// NOTE: To avoid deadlocks, do not lock m_attachments and then perform other tasks under that lock. Take a copy | ||
125 | /// of the list and act on that instead. | ||
124 | /// </remarks> | 126 | /// </remarks> |
125 | private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); | 127 | private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); |
126 | 128 | ||
@@ -971,19 +973,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
971 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | 973 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently |
972 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | 974 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are |
973 | // not transporting the required data. | 975 | // not transporting the required data. |
974 | lock (m_attachments) | 976 | // |
977 | // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of | ||
978 | // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here | ||
979 | // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. | ||
980 | // | ||
981 | // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts(). | ||
982 | // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing | ||
983 | // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the | ||
984 | // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. | ||
985 | List<SceneObjectGroup> attachments = GetAttachments(); | ||
986 | |||
987 | if (attachments.Count > 0) | ||
975 | { | 988 | { |
976 | if (HasAttachments()) | 989 | m_log.DebugFormat( |
977 | { | 990 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); |
978 | m_log.DebugFormat( | ||
979 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); | ||
980 | 991 | ||
981 | // Resume scripts | 992 | // Resume scripts |
982 | foreach (SceneObjectGroup sog in m_attachments) | 993 | foreach (SceneObjectGroup sog in attachments) |
983 | { | 994 | { |
984 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); | 995 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); |
985 | sog.ResumeScripts(); | 996 | sog.ResumeScripts(); |
986 | } | ||
987 | } | 997 | } |
988 | } | 998 | } |
989 | } | 999 | } |