diff options
author | Justin Clark-Casey (justincc) | 2010-09-15 21:41:42 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2010-09-15 21:51:13 +0100 |
commit | 16f296f48932379a89c52f095eae199347f33407 (patch) | |
tree | 083f5e19ff4a5a349d7ddac5055bff1a1fd59cdd /OpenSim | |
parent | Remove long unused Region/Framework/ThreadTracker (diff) | |
download | opensim-SC_OLD-16f296f48932379a89c52f095eae199347f33407.zip opensim-SC_OLD-16f296f48932379a89c52f095eae199347f33407.tar.gz opensim-SC_OLD-16f296f48932379a89c52f095eae199347f33407.tar.bz2 opensim-SC_OLD-16f296f48932379a89c52f095eae199347f33407.tar.xz |
Instead of locking SOG.Children when a group is being removed from the scene, iterate over an unlocked list instead
Previously, deadlock was possible because deleting a group took a SOG.Children lock then an m_entityUpdates.SyncRoot lock in LLClientView
At the same time, a thread starting from LLClientView.ProcessEntityUpdates() could take an m_entityUpdates.SyncRoot lock then later attempt to take a SOG.Children lock in PermissionsModule.GenerateClientFlags() and later on
Taking a children list in SOG appears to be a better solution than changing PermissionsModule to not relook up the prim. Going the permission modules root would require that all downstream modules not take a SOG.Children lock either
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index dc6509d..99c2abf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -29,6 +29,7 @@ using System; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Drawing; | 30 | using System.Drawing; |
31 | using System.IO; | 31 | using System.IO; |
32 | using System.Linq; | ||
32 | using System.Threading; | 33 | using System.Threading; |
33 | using System.Xml; | 34 | using System.Xml; |
34 | using System.Xml.Serialization; | 35 | using System.Xml.Serialization; |
@@ -1236,26 +1237,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
1236 | /// <param name="silent">If true then deletion is not broadcast to clients</param> | 1237 | /// <param name="silent">If true then deletion is not broadcast to clients</param> |
1237 | public void DeleteGroup(bool silent) | 1238 | public void DeleteGroup(bool silent) |
1238 | { | 1239 | { |
1240 | List<SceneObjectPart> parts; | ||
1241 | |||
1239 | lock (m_parts) | 1242 | lock (m_parts) |
1243 | parts = m_parts.Values.ToList(); | ||
1244 | |||
1245 | foreach (SceneObjectPart part in parts) | ||
1240 | { | 1246 | { |
1241 | foreach (SceneObjectPart part in m_parts.Values) | 1247 | Scene.ForEachScenePresence(delegate(ScenePresence avatar) |
1242 | { | 1248 | { |
1243 | // part.Inventory.RemoveScriptInstances(); | 1249 | if (avatar.ParentID == LocalId) |
1244 | Scene.ForEachScenePresence(delegate(ScenePresence avatar) | ||
1245 | { | 1250 | { |
1246 | if (avatar.ParentID == LocalId) | 1251 | avatar.StandUp(); |
1247 | { | 1252 | } |
1248 | avatar.StandUp(); | ||
1249 | } | ||
1250 | 1253 | ||
1251 | if (!silent) | 1254 | if (!silent) |
1252 | { | 1255 | { |
1253 | part.UpdateFlag = 0; | 1256 | part.UpdateFlag = 0; |
1254 | if (part == m_rootPart) | 1257 | if (part == m_rootPart) |
1255 | avatar.ControllingClient.SendKillObject(m_regionHandle, part.LocalId); | 1258 | avatar.ControllingClient.SendKillObject(m_regionHandle, part.LocalId); |
1256 | } | 1259 | } |
1257 | }); | 1260 | }); |
1258 | } | ||
1259 | } | 1261 | } |
1260 | } | 1262 | } |
1261 | 1263 | ||