diff options
author | Justin Clark-Casey (justincc) | 2010-08-26 00:08:53 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2010-08-26 00:08:53 +0100 |
commit | 8031f8ec09df4f654c86a9c7bc498664f7b9d9dc (patch) | |
tree | d6a6da4d448b9bc11ff8d1078b9be089b9872151 /OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |
parent | minor: remove mono compiler warning (diff) | |
download | opensim-SC_OLD-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.zip opensim-SC_OLD-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.gz opensim-SC_OLD-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.bz2 opensim-SC_OLD-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.xz |
Improve consistency of locking for SOG.m_parts in order to avoid race conditions in linking and unlinking
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 131 |
1 files changed, 79 insertions, 52 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 952d280..5ee8d73 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -213,7 +213,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
213 | /// </summary> | 213 | /// </summary> |
214 | public int PrimCount | 214 | public int PrimCount |
215 | { | 215 | { |
216 | get { return m_parts.Count; } | 216 | get { lock (m_parts) { return m_parts.Count; } } |
217 | } | 217 | } |
218 | 218 | ||
219 | protected Quaternion m_rotation = Quaternion.Identity; | 219 | protected Quaternion m_rotation = Quaternion.Identity; |
@@ -237,6 +237,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
237 | 237 | ||
238 | /// <value> | 238 | /// <value> |
239 | /// The parts of this scene object group. You must lock this property before using it. | 239 | /// The parts of this scene object group. You must lock this property before using it. |
240 | /// If you want to know the number of children, consider using the PrimCount property instead | ||
240 | /// </value> | 241 | /// </value> |
241 | public Dictionary<UUID, SceneObjectPart> Children | 242 | public Dictionary<UUID, SceneObjectPart> Children |
242 | { | 243 | { |
@@ -298,6 +299,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
298 | { | 299 | { |
299 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | 300 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); |
300 | } | 301 | } |
302 | |||
301 | if (RootPart.GetStatusSandbox()) | 303 | if (RootPart.GetStatusSandbox()) |
302 | { | 304 | { |
303 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) | 305 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) |
@@ -308,6 +310,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
308 | return; | 310 | return; |
309 | } | 311 | } |
310 | } | 312 | } |
313 | |||
311 | lock (m_parts) | 314 | lock (m_parts) |
312 | { | 315 | { |
313 | foreach (SceneObjectPart part in m_parts.Values) | 316 | foreach (SceneObjectPart part in m_parts.Values) |
@@ -558,21 +561,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
558 | if (m_rootPart.LocalId == 0) | 561 | if (m_rootPart.LocalId == 0) |
559 | m_rootPart.LocalId = m_scene.AllocateLocalId(); | 562 | m_rootPart.LocalId = m_scene.AllocateLocalId(); |
560 | 563 | ||
561 | // No need to lock here since the object isn't yet in a scene | 564 | lock (m_parts) |
562 | foreach (SceneObjectPart part in m_parts.Values) | ||
563 | { | 565 | { |
564 | if (Object.ReferenceEquals(part, m_rootPart)) | 566 | foreach (SceneObjectPart part in m_parts.Values) |
565 | { | ||
566 | continue; | ||
567 | } | ||
568 | |||
569 | if (part.LocalId == 0) | ||
570 | { | 567 | { |
571 | part.LocalId = m_scene.AllocateLocalId(); | 568 | if (Object.ReferenceEquals(part, m_rootPart)) |
569 | { | ||
570 | continue; | ||
571 | } | ||
572 | |||
573 | if (part.LocalId == 0) | ||
574 | { | ||
575 | part.LocalId = m_scene.AllocateLocalId(); | ||
576 | } | ||
577 | |||
578 | part.ParentID = m_rootPart.LocalId; | ||
579 | //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); | ||
572 | } | 580 | } |
573 | |||
574 | part.ParentID = m_rootPart.LocalId; | ||
575 | //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); | ||
576 | } | 581 | } |
577 | 582 | ||
578 | ApplyPhysics(m_scene.m_physicalPrim); | 583 | ApplyPhysics(m_scene.m_physicalPrim); |
@@ -670,7 +675,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
670 | minY = 256f; | 675 | minY = 256f; |
671 | minZ = 8192f; | 676 | minZ = 8192f; |
672 | 677 | ||
673 | lock(m_parts); | 678 | lock(m_parts) |
674 | { | 679 | { |
675 | foreach (SceneObjectPart part in m_parts.Values) | 680 | foreach (SceneObjectPart part in m_parts.Values) |
676 | { | 681 | { |
@@ -995,9 +1000,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
995 | m_rootPart.AttachedAvatar = agentID; | 1000 | m_rootPart.AttachedAvatar = agentID; |
996 | 1001 | ||
997 | //Anakin Lohner bug #3839 | 1002 | //Anakin Lohner bug #3839 |
998 | foreach (SceneObjectPart p in m_parts.Values) | 1003 | lock (m_parts) |
999 | { | 1004 | { |
1000 | p.AttachedAvatar = agentID; | 1005 | foreach (SceneObjectPart p in m_parts.Values) |
1006 | { | ||
1007 | p.AttachedAvatar = agentID; | ||
1008 | } | ||
1001 | } | 1009 | } |
1002 | 1010 | ||
1003 | if (m_rootPart.PhysActor != null) | 1011 | if (m_rootPart.PhysActor != null) |
@@ -1065,10 +1073,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1065 | 1073 | ||
1066 | AbsolutePosition = detachedpos; | 1074 | AbsolutePosition = detachedpos; |
1067 | m_rootPart.AttachedAvatar = UUID.Zero; | 1075 | m_rootPart.AttachedAvatar = UUID.Zero; |
1068 | //Anakin Lohner bug #3839 | 1076 | |
1069 | foreach (SceneObjectPart p in m_parts.Values) | 1077 | //Anakin Lohner bug #3839 |
1078 | lock (m_parts) | ||
1070 | { | 1079 | { |
1071 | p.AttachedAvatar = UUID.Zero; | 1080 | foreach (SceneObjectPart p in m_parts.Values) |
1081 | { | ||
1082 | p.AttachedAvatar = UUID.Zero; | ||
1083 | } | ||
1072 | } | 1084 | } |
1073 | 1085 | ||
1074 | m_rootPart.SetParentLocalId(0); | 1086 | m_rootPart.SetParentLocalId(0); |
@@ -1094,10 +1106,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1094 | } | 1106 | } |
1095 | 1107 | ||
1096 | m_rootPart.AttachedAvatar = UUID.Zero; | 1108 | m_rootPart.AttachedAvatar = UUID.Zero; |
1109 | |||
1097 | //Anakin Lohner bug #3839 | 1110 | //Anakin Lohner bug #3839 |
1098 | foreach (SceneObjectPart p in m_parts.Values) | 1111 | lock (m_parts) |
1099 | { | 1112 | { |
1100 | p.AttachedAvatar = UUID.Zero; | 1113 | foreach (SceneObjectPart p in m_parts.Values) |
1114 | { | ||
1115 | p.AttachedAvatar = UUID.Zero; | ||
1116 | } | ||
1101 | } | 1117 | } |
1102 | 1118 | ||
1103 | m_rootPart.SetParentLocalId(0); | 1119 | m_rootPart.SetParentLocalId(0); |
@@ -1160,9 +1176,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1160 | part.ParentID = 0; | 1176 | part.ParentID = 0; |
1161 | part.LinkNum = 0; | 1177 | part.LinkNum = 0; |
1162 | 1178 | ||
1163 | // No locking required since the SOG should not be in the scene yet - one can't change root parts after | 1179 | lock (m_parts) |
1164 | // the scene object has been attached to the scene | 1180 | m_parts.Add(m_rootPart.UUID, m_rootPart); |
1165 | m_parts.Add(m_rootPart.UUID, m_rootPart); | ||
1166 | } | 1181 | } |
1167 | 1182 | ||
1168 | /// <summary> | 1183 | /// <summary> |
@@ -1625,7 +1640,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1625 | } | 1640 | } |
1626 | 1641 | ||
1627 | /// <summary> | 1642 | /// <summary> |
1628 | /// | 1643 | /// Copy the given part as the root part of this scene object. |
1629 | /// </summary> | 1644 | /// </summary> |
1630 | /// <param name="part"></param> | 1645 | /// <param name="part"></param> |
1631 | /// <param name="cAgentID"></param> | 1646 | /// <param name="cAgentID"></param> |
@@ -1882,11 +1897,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1882 | /// <param name="cGroupID"></param> | 1897 | /// <param name="cGroupID"></param> |
1883 | public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) | 1898 | public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) |
1884 | { | 1899 | { |
1885 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); | 1900 | SceneObjectPart newPart = null; |
1886 | newPart.SetParent(this); | 1901 | |
1887 | |||
1888 | lock (m_parts) | 1902 | lock (m_parts) |
1889 | { | 1903 | { |
1904 | newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); | ||
1905 | newPart.SetParent(this); | ||
1890 | m_parts.Add(newPart.UUID, newPart); | 1906 | m_parts.Add(newPart.UUID, newPart); |
1891 | } | 1907 | } |
1892 | 1908 | ||
@@ -1903,14 +1919,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1903 | /// </summary> | 1919 | /// </summary> |
1904 | public void ResetIDs() | 1920 | public void ResetIDs() |
1905 | { | 1921 | { |
1906 | // As this is only ever called for prims which are not currently part of the scene (and hence | 1922 | lock (m_parts) |
1907 | // not accessible by clients), there should be no need to lock | ||
1908 | List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values); | ||
1909 | m_parts.Clear(); | ||
1910 | foreach (SceneObjectPart part in partsList) | ||
1911 | { | 1923 | { |
1912 | part.ResetIDs(part.LinkNum); // Don't change link nums | 1924 | List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values); |
1913 | m_parts.Add(part.UUID, part); | 1925 | m_parts.Clear(); |
1926 | foreach (SceneObjectPart part in partsList) | ||
1927 | { | ||
1928 | part.ResetIDs(part.LinkNum); // Don't change link nums | ||
1929 | m_parts.Add(part.UUID, part); | ||
1930 | } | ||
1914 | } | 1931 | } |
1915 | } | 1932 | } |
1916 | 1933 | ||
@@ -2136,10 +2153,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2136 | public SceneObjectPart GetChildPart(UUID primID) | 2153 | public SceneObjectPart GetChildPart(UUID primID) |
2137 | { | 2154 | { |
2138 | SceneObjectPart childPart = null; | 2155 | SceneObjectPart childPart = null; |
2139 | if (m_parts.ContainsKey(primID)) | 2156 | |
2157 | lock (m_parts) | ||
2140 | { | 2158 | { |
2141 | childPart = m_parts[primID]; | 2159 | if (m_parts.ContainsKey(primID)) |
2160 | { | ||
2161 | childPart = m_parts[primID]; | ||
2162 | } | ||
2142 | } | 2163 | } |
2164 | |||
2143 | return childPart; | 2165 | return childPart; |
2144 | } | 2166 | } |
2145 | 2167 | ||
@@ -2174,9 +2196,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2174 | /// <returns></returns> | 2196 | /// <returns></returns> |
2175 | public bool HasChildPrim(UUID primID) | 2197 | public bool HasChildPrim(UUID primID) |
2176 | { | 2198 | { |
2177 | if (m_parts.ContainsKey(primID)) | 2199 | lock (m_parts) |
2178 | { | 2200 | { |
2179 | return true; | 2201 | if (m_parts.ContainsKey(primID)) |
2202 | return true; | ||
2180 | } | 2203 | } |
2181 | 2204 | ||
2182 | return false; | 2205 | return false; |
@@ -2370,17 +2393,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2370 | lock (m_parts) | 2393 | lock (m_parts) |
2371 | { | 2394 | { |
2372 | m_parts.Remove(linkPart.UUID); | 2395 | m_parts.Remove(linkPart.UUID); |
2373 | } | 2396 | |
2374 | 2397 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left | |
2375 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left | ||
2376 | RootPart.LinkNum = 0; | ||
2377 | else | ||
2378 | { | ||
2379 | foreach (SceneObjectPart p in m_parts.Values) | ||
2380 | { | 2398 | { |
2381 | if (p.LinkNum > linkPart.LinkNum) | 2399 | RootPart.LinkNum = 0; |
2382 | p.LinkNum--; | ||
2383 | } | 2400 | } |
2401 | else | ||
2402 | { | ||
2403 | foreach (SceneObjectPart p in m_parts.Values) | ||
2404 | { | ||
2405 | if (p.LinkNum > linkPart.LinkNum) | ||
2406 | p.LinkNum--; | ||
2407 | } | ||
2408 | } | ||
2384 | } | 2409 | } |
2385 | 2410 | ||
2386 | linkPart.ParentID = 0; | 2411 | linkPart.ParentID = 0; |
@@ -2762,9 +2787,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2762 | public void UpdatePermissions(UUID AgentID, byte field, uint localID, | 2787 | public void UpdatePermissions(UUID AgentID, byte field, uint localID, |
2763 | uint mask, byte addRemTF) | 2788 | uint mask, byte addRemTF) |
2764 | { | 2789 | { |
2765 | foreach (SceneObjectPart part in m_parts.Values) | 2790 | lock (m_parts) |
2766 | part.UpdatePermissions(AgentID, field, localID, mask, | 2791 | { |
2767 | addRemTF); | 2792 | foreach (SceneObjectPart part in m_parts.Values) |
2793 | part.UpdatePermissions(AgentID, field, localID, mask, addRemTF); | ||
2794 | } | ||
2768 | 2795 | ||
2769 | HasGroupChanged = true; | 2796 | HasGroupChanged = true; |
2770 | } | 2797 | } |