diff options
author | Justin Clark-Casey (justincc) | 2013-06-05 22:20:48 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2013-06-05 22:20:48 +0100 |
commit | f41fc4eb25ade48a358511564f3911a4605c1c31 (patch) | |
tree | df8e2bd67efc677c2846d493539ae4b78ea3d055 | |
parent | BulletSim: default PhysicsTimeStep to same as the simulator's (diff) | |
download | opensim-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.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 | } |