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 | |
parent | minor: remove mono compiler warning (diff) | |
download | opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.zip opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.gz opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.bz2 opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.xz |
Improve consistency of locking for SOG.m_parts in order to avoid race conditions in linking and unlinking
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 21 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 38 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 35 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 111 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 131 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 5 |
6 files changed, 205 insertions, 136 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 9fef8f4..379128a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -1974,7 +1974,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1974 | if (null == group) | 1974 | if (null == group) |
1975 | return null; | 1975 | return null; |
1976 | 1976 | ||
1977 | if (!Permissions.CanRezObject(group.Children.Count, item.OwnerID, pos)) | 1977 | if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos)) |
1978 | return null; | 1978 | return null; |
1979 | 1979 | ||
1980 | if (!Permissions.BypassPermissions()) | 1980 | if (!Permissions.BypassPermissions()) |
@@ -2051,8 +2051,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2051 | sog.SetGroup(groupID, remoteClient); | 2051 | sog.SetGroup(groupID, remoteClient); |
2052 | sog.ScheduleGroupForFullUpdate(); | 2052 | sog.ScheduleGroupForFullUpdate(); |
2053 | 2053 | ||
2054 | foreach (SceneObjectPart child in sog.Children.Values) | 2054 | lock (sog.Children) |
2055 | child.Inventory.ChangeInventoryOwner(ownerID); | 2055 | { |
2056 | foreach (SceneObjectPart child in sog.Children.Values) | ||
2057 | child.Inventory.ChangeInventoryOwner(ownerID); | ||
2058 | } | ||
2056 | } | 2059 | } |
2057 | else | 2060 | else |
2058 | { | 2061 | { |
@@ -2062,16 +2065,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2062 | if (sog.GroupID != groupID) | 2065 | if (sog.GroupID != groupID) |
2063 | continue; | 2066 | continue; |
2064 | 2067 | ||
2065 | foreach (SceneObjectPart child in sog.Children.Values) | 2068 | lock (sog.Children) |
2066 | { | 2069 | { |
2067 | child.LastOwnerID = child.OwnerID; | 2070 | foreach (SceneObjectPart child in sog.Children.Values) |
2068 | child.Inventory.ChangeInventoryOwner(groupID); | 2071 | { |
2072 | child.LastOwnerID = child.OwnerID; | ||
2073 | child.Inventory.ChangeInventoryOwner(groupID); | ||
2074 | } | ||
2069 | } | 2075 | } |
2070 | 2076 | ||
2071 | sog.SetOwnerId(groupID); | 2077 | sog.SetOwnerId(groupID); |
2072 | sog.ApplyNextOwnerPermissions(); | 2078 | sog.ApplyNextOwnerPermissions(); |
2073 | } | 2079 | } |
2074 | |||
2075 | } | 2080 | } |
2076 | 2081 | ||
2077 | foreach (uint localID in localIDs) | 2082 | foreach (uint localID in localIDs) |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index e25b1f1..9f1575d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | |||
@@ -156,21 +156,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
156 | } | 156 | } |
157 | break; | 157 | break; |
158 | } | 158 | } |
159 | else | 159 | else |
160 | { | 160 | { |
161 | // We also need to check the children of this prim as they | 161 | // We also need to check the children of this prim as they |
162 | // can be selected as well and send property information | 162 | // can be selected as well and send property information |
163 | bool foundPrim = false; | 163 | bool foundPrim = false; |
164 | foreach (KeyValuePair<UUID, SceneObjectPart> child in ((SceneObjectGroup) ent).Children) | 164 | |
165 | { | 165 | SceneObjectGroup sog = ent as SceneObjectGroup; |
166 | if (child.Value.LocalId == primLocalID) | 166 | |
167 | { | 167 | lock (sog.Children) |
168 | child.Value.GetProperties(remoteClient); | 168 | { |
169 | foundPrim = true; | 169 | foreach (KeyValuePair<UUID, SceneObjectPart> child in (sog.Children)) |
170 | break; | 170 | { |
171 | } | 171 | if (child.Value.LocalId == primLocalID) |
172 | } | 172 | { |
173 | if (foundPrim) break; | 173 | child.Value.GetProperties(remoteClient); |
174 | foundPrim = true; | ||
175 | break; | ||
176 | } | ||
177 | } | ||
178 | } | ||
179 | |||
180 | if (foundPrim) | ||
181 | break; | ||
174 | } | 182 | } |
175 | } | 183 | } |
176 | } | 184 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b808c6d..8556105 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1756,8 +1756,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1756 | 1756 | ||
1757 | if (group.RootPart == null) | 1757 | if (group.RootPart == null) |
1758 | { | 1758 | { |
1759 | m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", | 1759 | m_log.ErrorFormat( |
1760 | group.Children == null ? 0 : group.Children.Count); | 1760 | "[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", |
1761 | group.Children == null ? 0 : group.PrimCount); | ||
1761 | } | 1762 | } |
1762 | 1763 | ||
1763 | AddRestoredSceneObject(group, true, true); | 1764 | AddRestoredSceneObject(group, true, true); |
@@ -2064,18 +2065,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
2064 | group.RemoveScriptInstances(true); | 2065 | group.RemoveScriptInstances(true); |
2065 | } | 2066 | } |
2066 | 2067 | ||
2067 | foreach (SceneObjectPart part in group.Children.Values) | 2068 | lock (group.Children) |
2068 | { | 2069 | { |
2069 | if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) | 2070 | foreach (SceneObjectPart part in group.Children.Values) |
2070 | { | 2071 | { |
2071 | PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? | 2072 | if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) |
2072 | } | 2073 | { |
2073 | else if (part.PhysActor != null) | 2074 | PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? |
2074 | { | 2075 | } |
2075 | PhysicsScene.RemovePrim(part.PhysActor); | 2076 | else if (part.PhysActor != null) |
2076 | part.PhysActor = null; | 2077 | { |
2078 | PhysicsScene.RemovePrim(part.PhysActor); | ||
2079 | part.PhysActor = null; | ||
2080 | } | ||
2077 | } | 2081 | } |
2078 | } | 2082 | } |
2083 | |||
2079 | // if (rootPart.PhysActor != null) | 2084 | // if (rootPart.PhysActor != null) |
2080 | // { | 2085 | // { |
2081 | // PhysicsScene.RemovePrim(rootPart.PhysActor); | 2086 | // PhysicsScene.RemovePrim(rootPart.PhysActor); |
@@ -2426,14 +2431,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2426 | 2431 | ||
2427 | // Force allocation of new LocalId | 2432 | // Force allocation of new LocalId |
2428 | // | 2433 | // |
2429 | foreach (SceneObjectPart p in sceneObject.Children.Values) | 2434 | lock (sceneObject.Children) |
2430 | p.LocalId = 0; | 2435 | { |
2436 | foreach (SceneObjectPart p in sceneObject.Children.Values) | ||
2437 | p.LocalId = 0; | ||
2438 | } | ||
2431 | 2439 | ||
2432 | if (sceneObject.IsAttachmentCheckFull()) // Attachment | 2440 | if (sceneObject.IsAttachmentCheckFull()) // Attachment |
2433 | { | 2441 | { |
2434 | sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); | 2442 | sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); |
2435 | sceneObject.RootPart.AddFlag(PrimFlags.Phantom); | 2443 | sceneObject.RootPart.AddFlag(PrimFlags.Phantom); |
2436 | |||
2437 | 2444 | ||
2438 | // Don't sent a full update here because this will cause full updates to be sent twice for | 2445 | // Don't sent a full update here because this will cause full updates to be sent twice for |
2439 | // attachments on region crossings, resulting in viewer glitches. | 2446 | // attachments on region crossings, resulting in viewer glitches. |
@@ -2447,7 +2454,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2447 | 2454 | ||
2448 | if (sp != null) | 2455 | if (sp != null) |
2449 | { | 2456 | { |
2450 | |||
2451 | SceneObjectGroup grp = sceneObject; | 2457 | SceneObjectGroup grp = sceneObject; |
2452 | 2458 | ||
2453 | m_log.DebugFormat( | 2459 | m_log.DebugFormat( |
@@ -2459,7 +2465,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2459 | 2465 | ||
2460 | if (AttachmentsModule != null) | 2466 | if (AttachmentsModule != null) |
2461 | AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false); | 2467 | AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false); |
2462 | |||
2463 | } | 2468 | } |
2464 | else | 2469 | else |
2465 | { | 2470 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 31faeec..2b24706 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -364,45 +364,48 @@ namespace OpenSim.Region.Framework.Scenes | |||
364 | // "[SCENE GRAPH]: Adding object {0} {1} to region {2}", | 364 | // "[SCENE GRAPH]: Adding object {0} {1} to region {2}", |
365 | // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); | 365 | // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); |
366 | 366 | ||
367 | if (m_parentScene.m_clampPrimSize) | 367 | lock (sceneObject.Children) |
368 | { | 368 | { |
369 | foreach (SceneObjectPart part in sceneObject.Children.Values) | 369 | if (m_parentScene.m_clampPrimSize) |
370 | { | 370 | { |
371 | Vector3 scale = part.Shape.Scale; | 371 | foreach (SceneObjectPart part in sceneObject.Children.Values) |
372 | 372 | { | |
373 | if (scale.X > m_parentScene.m_maxNonphys) | 373 | Vector3 scale = part.Shape.Scale; |
374 | scale.X = m_parentScene.m_maxNonphys; | 374 | |
375 | if (scale.Y > m_parentScene.m_maxNonphys) | 375 | if (scale.X > m_parentScene.m_maxNonphys) |
376 | scale.Y = m_parentScene.m_maxNonphys; | 376 | scale.X = m_parentScene.m_maxNonphys; |
377 | if (scale.Z > m_parentScene.m_maxNonphys) | 377 | if (scale.Y > m_parentScene.m_maxNonphys) |
378 | scale.Z = m_parentScene.m_maxNonphys; | 378 | scale.Y = m_parentScene.m_maxNonphys; |
379 | 379 | if (scale.Z > m_parentScene.m_maxNonphys) | |
380 | part.Shape.Scale = scale; | 380 | scale.Z = m_parentScene.m_maxNonphys; |
381 | |||
382 | part.Shape.Scale = scale; | ||
383 | } | ||
381 | } | 384 | } |
382 | } | 385 | |
386 | sceneObject.AttachToScene(m_parentScene); | ||
387 | |||
388 | if (sendClientUpdates) | ||
389 | sceneObject.ScheduleGroupForFullUpdate(); | ||
390 | |||
391 | Entities.Add(sceneObject); | ||
392 | m_numPrim += sceneObject.Children.Count; | ||
383 | 393 | ||
384 | sceneObject.AttachToScene(m_parentScene); | 394 | if (attachToBackup) |
395 | sceneObject.AttachToBackup(); | ||
385 | 396 | ||
386 | if (sendClientUpdates) | 397 | if (OnObjectCreate != null) |
387 | sceneObject.ScheduleGroupForFullUpdate(); | 398 | OnObjectCreate(sceneObject); |
388 | 399 | ||
389 | Entities.Add(sceneObject); | 400 | lock (m_dictionary_lock) |
390 | m_numPrim += sceneObject.Children.Count; | ||
391 | |||
392 | if (attachToBackup) | ||
393 | sceneObject.AttachToBackup(); | ||
394 | |||
395 | if (OnObjectCreate != null) | ||
396 | OnObjectCreate(sceneObject); | ||
397 | |||
398 | lock (m_dictionary_lock) | ||
399 | { | ||
400 | SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; | ||
401 | SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; | ||
402 | foreach (SceneObjectPart part in sceneObject.Children.Values) | ||
403 | { | 401 | { |
404 | SceneObjectGroupsByFullID[part.UUID] = sceneObject; | 402 | SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; |
405 | SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; | 403 | SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; |
404 | foreach (SceneObjectPart part in sceneObject.Children.Values) | ||
405 | { | ||
406 | SceneObjectGroupsByFullID[part.UUID] = sceneObject; | ||
407 | SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; | ||
408 | } | ||
406 | } | 409 | } |
407 | } | 410 | } |
408 | } | 411 | } |
@@ -420,11 +423,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
420 | { | 423 | { |
421 | if (!resultOfObjectLinked) | 424 | if (!resultOfObjectLinked) |
422 | { | 425 | { |
423 | m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count; | 426 | SceneObjectGroup sog = Entities[uuid] as SceneObjectGroup; |
424 | 427 | ||
425 | if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) | 428 | lock (sog.Children) |
426 | { | 429 | { |
427 | RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count); | 430 | m_numPrim -= sog.PrimCount; |
431 | |||
432 | if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) | ||
433 | { | ||
434 | RemovePhysicalPrim(sog.PrimCount); | ||
435 | } | ||
428 | } | 436 | } |
429 | } | 437 | } |
430 | 438 | ||
@@ -1603,7 +1611,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1603 | { | 1611 | { |
1604 | if (part != null) | 1612 | if (part != null) |
1605 | { | 1613 | { |
1606 | if (part.ParentGroup.Children.Count != 1) // Skip single | 1614 | if (part.ParentGroup.PrimCount != 1) // Skip single |
1607 | { | 1615 | { |
1608 | if (part.LinkNum < 2) // Root | 1616 | if (part.LinkNum < 2) // Root |
1609 | rootParts.Add(part); | 1617 | rootParts.Add(part); |
@@ -1631,8 +1639,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1631 | // However, editing linked parts and unlinking may be different | 1639 | // However, editing linked parts and unlinking may be different |
1632 | // | 1640 | // |
1633 | SceneObjectGroup group = root.ParentGroup; | 1641 | SceneObjectGroup group = root.ParentGroup; |
1634 | List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values); | 1642 | |
1635 | int numChildren = group.Children.Count; | 1643 | List<SceneObjectPart> newSet = null; |
1644 | int numChildren = -1; | ||
1645 | |||
1646 | lock (group.Children) | ||
1647 | { | ||
1648 | newSet = new List<SceneObjectPart>(group.Children.Values); | ||
1649 | numChildren = group.PrimCount; | ||
1650 | } | ||
1636 | 1651 | ||
1637 | // If there are prims left in a link set, but the root is | 1652 | // If there are prims left in a link set, but the root is |
1638 | // slated for unlink, we need to do this | 1653 | // slated for unlink, we need to do this |
@@ -1711,12 +1726,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1711 | { | 1726 | { |
1712 | if (ent is SceneObjectGroup) | 1727 | if (ent is SceneObjectGroup) |
1713 | { | 1728 | { |
1714 | foreach (KeyValuePair<UUID, SceneObjectPart> subent in ((SceneObjectGroup)ent).Children) | 1729 | SceneObjectGroup sog = ent as SceneObjectGroup; |
1730 | |||
1731 | lock (sog.Children) | ||
1715 | { | 1732 | { |
1716 | if (subent.Value.LocalId == localID) | 1733 | foreach (KeyValuePair<UUID, SceneObjectPart> subent in sog.Children) |
1717 | { | 1734 | { |
1718 | objid = subent.Key; | 1735 | if (subent.Value.LocalId == localID) |
1719 | obj = subent.Value; | 1736 | { |
1737 | objid = subent.Key; | ||
1738 | obj = subent.Value; | ||
1739 | } | ||
1720 | } | 1740 | } |
1721 | } | 1741 | } |
1722 | } | 1742 | } |
@@ -1781,7 +1801,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1781 | SceneObjectGroup original = GetGroupByPrim(originalPrimID); | 1801 | SceneObjectGroup original = GetGroupByPrim(originalPrimID); |
1782 | if (original != null) | 1802 | if (original != null) |
1783 | { | 1803 | { |
1784 | if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition)) | 1804 | if (m_parentScene.Permissions.CanDuplicateObject( |
1805 | original.PrimCount, original.UUID, AgentID, original.AbsolutePosition)) | ||
1785 | { | 1806 | { |
1786 | SceneObjectGroup copy = original.Copy(true); | 1807 | SceneObjectGroup copy = original.Copy(true); |
1787 | copy.AbsolutePosition = copy.AbsolutePosition + offset; | 1808 | copy.AbsolutePosition = copy.AbsolutePosition + offset; |
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 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 84b7365..e08fa77 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -601,7 +601,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
601 | rootPart.Name = item.Name; | 601 | rootPart.Name = item.Name; |
602 | rootPart.Description = item.Description; | 602 | rootPart.Description = item.Description; |
603 | 603 | ||
604 | List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values); | 604 | List<SceneObjectPart> partList = null; |
605 | |||
606 | lock (group.Children) | ||
607 | partList = new List<SceneObjectPart>(group.Children.Values); | ||
605 | 608 | ||
606 | group.SetGroup(m_part.GroupID, null); | 609 | group.SetGroup(m_part.GroupID, null); |
607 | 610 | ||