aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-06-05 22:20:48 +0100
committerJustin Clark-Casey (justincc)2013-06-05 22:20:48 +0100
commitf41fc4eb25ade48a358511564f3911a4605c1c31 (patch)
treedf8e2bd67efc677c2846d493539ae4b78ea3d055
parentBulletSim: default PhysicsTimeStep to same as the simulator's (diff)
downloadopensim-SC_OLD-f41fc4eb25ade48a358511564f3911a4605c1c31.zip
opensim-SC_OLD-f41fc4eb25ade48a358511564f3911a4605c1c31.tar.gz
opensim-SC_OLD-f41fc4eb25ade48a358511564f3911a4605c1c31.tar.bz2
opensim-SC_OLD-f41fc4eb25ade48a358511564f3911a4605c1c31.tar.xz
Avoid a deadlock where a script can attempt to take a ScriptInstance.m_Scripts lock then a lock on SP.m_attachments whilst SP.MakeRootAgent() attempts to take in the opposite order.
This is because scripts (at least on XEngine) start unsuspended - deceptively the ResumeScripts() calls in various places in the code are actually completely redundant (and useless). The solution chosen here is to use a copy of the SP attachments and not have the list locked whilst creating the scripts when an avatar enters the region. This looks to address http://opensimulator.org/mantis/view.php?id=6557
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs32
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 }