aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneGraph.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/SceneGraph.cs
parentminor: remove mono compiler warning (diff)
downloadopensim-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.cs111
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;