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/SceneGraph.cs | |
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/Scenes/SceneGraph.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 111 |
1 files changed, 66 insertions, 45 deletions
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; |