aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2010-08-26 00:08:53 +0100
committerJustin Clark-Casey (justincc)2010-08-26 00:08:53 +0100
commit8031f8ec09df4f654c86a9c7bc498664f7b9d9dc (patch)
treed6a6da4d448b9bc11ff8d1078b9be089b9872151 /OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
parentminor: remove mono compiler warning (diff)
downloadopensim-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.cs131
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 }