From 8031f8ec09df4f654c86a9c7bc498664f7b9d9dc Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 26 Aug 2010 00:08:53 +0100
Subject: Improve consistency of locking for SOG.m_parts in order to avoid race
conditions in linking and unlinking
---
OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs | 94 ++--
OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 210 ++++-----
OpenSim/Data/SQLite/SQLiteRegionData.cs | 9 +-
OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs | 9 +-
.../Avatar/Attachments/AttachmentsModule.cs | 2 +-
.../InventoryAccess/InventoryAccessModule.cs | 6 +-
.../World/Archiver/ArchiveReadRequest.cs | 55 +--
.../World/Objects/BuySell/BuySellModule.cs | 5 +-
.../CoreModules/World/WorldMap/MapImageModule.cs | 512 +++++++++++----------
OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 21 +-
.../Framework/Scenes/Scene.PacketHandlers.cs | 38 +-
OpenSim/Region/Framework/Scenes/Scene.cs | 35 +-
OpenSim/Region/Framework/Scenes/SceneGraph.cs | 111 +++--
.../Region/Framework/Scenes/SceneObjectGroup.cs | 131 +++---
.../Framework/Scenes/SceneObjectPartInventory.cs | 5 +-
.../ContentManagementSystem/CMEntityCollection.cs | 19 +-
.../ContentManagementSystem/CMModel.cs | 35 +-
.../ContentManagementSystem/CMView.cs | 9 +-
.../ContentManagementEntity.cs | 173 +++----
.../ContentManagementSystem/MetaEntity.cs | 38 +-
.../Scripting/Minimodule/SOPObject.cs | 19 +-
.../Shared/Api/Implementation/LSL_Api.cs | 100 ++--
OpenSim/Region/ScriptEngine/Shared/Helpers.cs | 11 +-
23 files changed, 906 insertions(+), 741 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
index 7d017a6..4ce93e5 100644
--- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
@@ -232,66 +232,68 @@ namespace OpenSim.Data.MSSQL
///
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
{
- _Log.InfoFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count);
-
- using (SqlConnection conn = new SqlConnection(m_connectionString))
+ lock (obj.Children)
{
- conn.Open();
- SqlTransaction transaction = conn.BeginTransaction();
-
- try
+ _Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count);
+
+ using (SqlConnection conn = new SqlConnection(m_connectionString))
{
- foreach (SceneObjectPart sceneObjectPart in obj.Children.Values)
+ conn.Open();
+ SqlTransaction transaction = conn.BeginTransaction();
+
+ try
{
- //Update prim
- using (SqlCommand sqlCommand = conn.CreateCommand())
- {
- sqlCommand.Transaction = transaction;
- try
- {
- StoreSceneObjectPrim(sceneObjectPart, sqlCommand, obj.UUID, regionUUID);
- }
- catch (SqlException sqlEx)
- {
- _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrim SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber);
- throw;
- }
- }
-
- //Update primshapes
- using (SqlCommand sqlCommand = conn.CreateCommand())
+ foreach (SceneObjectPart sceneObjectPart in obj.Children.Values)
{
- sqlCommand.Transaction = transaction;
- try
+ //Update prim
+ using (SqlCommand sqlCommand = conn.CreateCommand())
{
- StoreSceneObjectPrimShapes(sceneObjectPart, sqlCommand, obj.UUID, regionUUID);
+ sqlCommand.Transaction = transaction;
+ try
+ {
+ StoreSceneObjectPrim(sceneObjectPart, sqlCommand, obj.UUID, regionUUID);
+ }
+ catch (SqlException sqlEx)
+ {
+ _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrim SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber);
+ throw;
+ }
}
- catch (SqlException sqlEx)
+
+ //Update primshapes
+ using (SqlCommand sqlCommand = conn.CreateCommand())
{
- _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrimShapes SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber);
- throw;
+ sqlCommand.Transaction = transaction;
+ try
+ {
+ StoreSceneObjectPrimShapes(sceneObjectPart, sqlCommand, obj.UUID, regionUUID);
+ }
+ catch (SqlException sqlEx)
+ {
+ _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrimShapes SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber);
+ throw;
+ }
}
}
+
+ transaction.Commit();
}
-
- transaction.Commit();
- }
- catch (Exception ex)
- {
- _Log.ErrorFormat("[REGION DB]: Store SceneObjectGroup error: {0}, Rolling back...", ex.Message);
- try
- {
- transaction.Rollback();
- }
- catch (Exception ex2)
+ catch (Exception ex)
{
- //Show error
- _Log.InfoFormat("[REGION DB]: Rollback of SceneObjectGroup store transaction failed with error: {0}", ex2.Message);
-
+ _Log.ErrorFormat("[REGION DB]: Store SceneObjectGroup error: {0}, Rolling back...", ex.Message);
+ try
+ {
+ transaction.Rollback();
+ }
+ catch (Exception ex2)
+ {
+ //Show error
+ _Log.InfoFormat("[REGION DB]: Rollback of SceneObjectGroup store transaction failed with error: {0}", ex2.Message);
+
+ }
}
}
}
-
}
///
diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
index 1edcb5d..b756b4f 100644
--- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
+++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
@@ -135,111 +135,115 @@ namespace OpenSim.Data.MySQL
dbcon.Open();
MySqlCommand cmd = dbcon.CreateCommand();
- foreach (SceneObjectPart prim in obj.Children.Values)
+ lock (obj.Children)
{
- cmd.Parameters.Clear();
-
- cmd.CommandText = "replace into prims (" +
- "UUID, CreationDate, " +
- "Name, Text, Description, " +
- "SitName, TouchName, ObjectFlags, " +
- "OwnerMask, NextOwnerMask, GroupMask, " +
- "EveryoneMask, BaseMask, PositionX, " +
- "PositionY, PositionZ, GroupPositionX, " +
- "GroupPositionY, GroupPositionZ, VelocityX, " +
- "VelocityY, VelocityZ, AngularVelocityX, " +
- "AngularVelocityY, AngularVelocityZ, " +
- "AccelerationX, AccelerationY, " +
- "AccelerationZ, RotationX, " +
- "RotationY, RotationZ, " +
- "RotationW, SitTargetOffsetX, " +
- "SitTargetOffsetY, SitTargetOffsetZ, " +
- "SitTargetOrientW, SitTargetOrientX, " +
- "SitTargetOrientY, SitTargetOrientZ, " +
- "RegionUUID, CreatorID, " +
- "OwnerID, GroupID, " +
- "LastOwnerID, SceneGroupID, " +
- "PayPrice, PayButton1, " +
- "PayButton2, PayButton3, " +
- "PayButton4, LoopedSound, " +
- "LoopedSoundGain, TextureAnimation, " +
- "OmegaX, OmegaY, OmegaZ, " +
- "CameraEyeOffsetX, CameraEyeOffsetY, " +
- "CameraEyeOffsetZ, CameraAtOffsetX, " +
- "CameraAtOffsetY, CameraAtOffsetZ, " +
- "ForceMouselook, ScriptAccessPin, " +
- "AllowedDrop, DieAtEdge, " +
- "SalePrice, SaleType, " +
- "ColorR, ColorG, ColorB, ColorA, " +
- "ParticleSystem, ClickAction, Material, " +
- "CollisionSound, CollisionSoundVolume, " +
- "PassTouches, " +
- "LinkNumber, MediaURL) values (" + "?UUID, " +
- "?CreationDate, ?Name, ?Text, " +
- "?Description, ?SitName, ?TouchName, " +
- "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
- "?GroupMask, ?EveryoneMask, ?BaseMask, " +
- "?PositionX, ?PositionY, ?PositionZ, " +
- "?GroupPositionX, ?GroupPositionY, " +
- "?GroupPositionZ, ?VelocityX, " +
- "?VelocityY, ?VelocityZ, ?AngularVelocityX, " +
- "?AngularVelocityY, ?AngularVelocityZ, " +
- "?AccelerationX, ?AccelerationY, " +
- "?AccelerationZ, ?RotationX, " +
- "?RotationY, ?RotationZ, " +
- "?RotationW, ?SitTargetOffsetX, " +
- "?SitTargetOffsetY, ?SitTargetOffsetZ, " +
- "?SitTargetOrientW, ?SitTargetOrientX, " +
- "?SitTargetOrientY, ?SitTargetOrientZ, " +
- "?RegionUUID, ?CreatorID, ?OwnerID, " +
- "?GroupID, ?LastOwnerID, ?SceneGroupID, " +
- "?PayPrice, ?PayButton1, ?PayButton2, " +
- "?PayButton3, ?PayButton4, ?LoopedSound, " +
- "?LoopedSoundGain, ?TextureAnimation, " +
- "?OmegaX, ?OmegaY, ?OmegaZ, " +
- "?CameraEyeOffsetX, ?CameraEyeOffsetY, " +
- "?CameraEyeOffsetZ, ?CameraAtOffsetX, " +
- "?CameraAtOffsetY, ?CameraAtOffsetZ, " +
- "?ForceMouselook, ?ScriptAccessPin, " +
- "?AllowedDrop, ?DieAtEdge, ?SalePrice, " +
- "?SaleType, ?ColorR, ?ColorG, " +
- "?ColorB, ?ColorA, ?ParticleSystem, " +
- "?ClickAction, ?Material, ?CollisionSound, " +
- "?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)";
-
- FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
-
- ExecuteNonQuery(cmd);
-
- cmd.Parameters.Clear();
-
- cmd.CommandText = "replace into primshapes (" +
- "UUID, Shape, ScaleX, ScaleY, " +
- "ScaleZ, PCode, PathBegin, PathEnd, " +
- "PathScaleX, PathScaleY, PathShearX, " +
- "PathShearY, PathSkew, PathCurve, " +
- "PathRadiusOffset, PathRevolutions, " +
- "PathTaperX, PathTaperY, PathTwist, " +
- "PathTwistBegin, ProfileBegin, ProfileEnd, " +
- "ProfileCurve, ProfileHollow, Texture, " +
- "ExtraParams, State, Media) values (?UUID, " +
- "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
- "?PCode, ?PathBegin, ?PathEnd, " +
- "?PathScaleX, ?PathScaleY, " +
- "?PathShearX, ?PathShearY, " +
- "?PathSkew, ?PathCurve, ?PathRadiusOffset, " +
- "?PathRevolutions, ?PathTaperX, " +
- "?PathTaperY, ?PathTwist, " +
- "?PathTwistBegin, ?ProfileBegin, " +
- "?ProfileEnd, ?ProfileCurve, " +
- "?ProfileHollow, ?Texture, ?ExtraParams, " +
- "?State, ?Media)";
-
- FillShapeCommand(cmd, prim);
-
- ExecuteNonQuery(cmd);
+ foreach (SceneObjectPart prim in obj.Children.Values)
+ {
+ cmd.Parameters.Clear();
+
+ cmd.CommandText = "replace into prims (" +
+ "UUID, CreationDate, " +
+ "Name, Text, Description, " +
+ "SitName, TouchName, ObjectFlags, " +
+ "OwnerMask, NextOwnerMask, GroupMask, " +
+ "EveryoneMask, BaseMask, PositionX, " +
+ "PositionY, PositionZ, GroupPositionX, " +
+ "GroupPositionY, GroupPositionZ, VelocityX, " +
+ "VelocityY, VelocityZ, AngularVelocityX, " +
+ "AngularVelocityY, AngularVelocityZ, " +
+ "AccelerationX, AccelerationY, " +
+ "AccelerationZ, RotationX, " +
+ "RotationY, RotationZ, " +
+ "RotationW, SitTargetOffsetX, " +
+ "SitTargetOffsetY, SitTargetOffsetZ, " +
+ "SitTargetOrientW, SitTargetOrientX, " +
+ "SitTargetOrientY, SitTargetOrientZ, " +
+ "RegionUUID, CreatorID, " +
+ "OwnerID, GroupID, " +
+ "LastOwnerID, SceneGroupID, " +
+ "PayPrice, PayButton1, " +
+ "PayButton2, PayButton3, " +
+ "PayButton4, LoopedSound, " +
+ "LoopedSoundGain, TextureAnimation, " +
+ "OmegaX, OmegaY, OmegaZ, " +
+ "CameraEyeOffsetX, CameraEyeOffsetY, " +
+ "CameraEyeOffsetZ, CameraAtOffsetX, " +
+ "CameraAtOffsetY, CameraAtOffsetZ, " +
+ "ForceMouselook, ScriptAccessPin, " +
+ "AllowedDrop, DieAtEdge, " +
+ "SalePrice, SaleType, " +
+ "ColorR, ColorG, ColorB, ColorA, " +
+ "ParticleSystem, ClickAction, Material, " +
+ "CollisionSound, CollisionSoundVolume, " +
+ "PassTouches, " +
+ "LinkNumber, MediaURL) values (" + "?UUID, " +
+ "?CreationDate, ?Name, ?Text, " +
+ "?Description, ?SitName, ?TouchName, " +
+ "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
+ "?GroupMask, ?EveryoneMask, ?BaseMask, " +
+ "?PositionX, ?PositionY, ?PositionZ, " +
+ "?GroupPositionX, ?GroupPositionY, " +
+ "?GroupPositionZ, ?VelocityX, " +
+ "?VelocityY, ?VelocityZ, ?AngularVelocityX, " +
+ "?AngularVelocityY, ?AngularVelocityZ, " +
+ "?AccelerationX, ?AccelerationY, " +
+ "?AccelerationZ, ?RotationX, " +
+ "?RotationY, ?RotationZ, " +
+ "?RotationW, ?SitTargetOffsetX, " +
+ "?SitTargetOffsetY, ?SitTargetOffsetZ, " +
+ "?SitTargetOrientW, ?SitTargetOrientX, " +
+ "?SitTargetOrientY, ?SitTargetOrientZ, " +
+ "?RegionUUID, ?CreatorID, ?OwnerID, " +
+ "?GroupID, ?LastOwnerID, ?SceneGroupID, " +
+ "?PayPrice, ?PayButton1, ?PayButton2, " +
+ "?PayButton3, ?PayButton4, ?LoopedSound, " +
+ "?LoopedSoundGain, ?TextureAnimation, " +
+ "?OmegaX, ?OmegaY, ?OmegaZ, " +
+ "?CameraEyeOffsetX, ?CameraEyeOffsetY, " +
+ "?CameraEyeOffsetZ, ?CameraAtOffsetX, " +
+ "?CameraAtOffsetY, ?CameraAtOffsetZ, " +
+ "?ForceMouselook, ?ScriptAccessPin, " +
+ "?AllowedDrop, ?DieAtEdge, ?SalePrice, " +
+ "?SaleType, ?ColorR, ?ColorG, " +
+ "?ColorB, ?ColorA, ?ParticleSystem, " +
+ "?ClickAction, ?Material, ?CollisionSound, " +
+ "?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)";
+
+ FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
+
+ ExecuteNonQuery(cmd);
+
+ cmd.Parameters.Clear();
+
+ cmd.CommandText = "replace into primshapes (" +
+ "UUID, Shape, ScaleX, ScaleY, " +
+ "ScaleZ, PCode, PathBegin, PathEnd, " +
+ "PathScaleX, PathScaleY, PathShearX, " +
+ "PathShearY, PathSkew, PathCurve, " +
+ "PathRadiusOffset, PathRevolutions, " +
+ "PathTaperX, PathTaperY, PathTwist, " +
+ "PathTwistBegin, ProfileBegin, ProfileEnd, " +
+ "ProfileCurve, ProfileHollow, Texture, " +
+ "ExtraParams, State, Media) values (?UUID, " +
+ "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
+ "?PCode, ?PathBegin, ?PathEnd, " +
+ "?PathScaleX, ?PathScaleY, " +
+ "?PathShearX, ?PathShearY, " +
+ "?PathSkew, ?PathCurve, ?PathRadiusOffset, " +
+ "?PathRevolutions, ?PathTaperX, " +
+ "?PathTaperY, ?PathTwist, " +
+ "?PathTwistBegin, ?ProfileBegin, " +
+ "?ProfileEnd, ?ProfileCurve, " +
+ "?ProfileHollow, ?Texture, ?ExtraParams, " +
+ "?State, ?Media)";
+
+ FillShapeCommand(cmd, prim);
+
+ ExecuteNonQuery(cmd);
+ }
+
+ cmd.Dispose();
}
- cmd.Dispose();
}
}
}
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index 4208050..bfd8279 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -360,10 +360,13 @@ namespace OpenSim.Data.SQLite
lock (ds)
{
- foreach (SceneObjectPart prim in obj.Children.Values)
+ lock (obj.Children)
{
-// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
- addPrim(prim, obj.UUID, regionUUID);
+ foreach (SceneObjectPart prim in obj.Children.Values)
+ {
+ // m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
+ addPrim(prim, obj.UUID, regionUUID);
+ }
}
}
diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs
index 289fd94..779b2ed 100644
--- a/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs
@@ -327,10 +327,13 @@ namespace OpenSim.Data.SQLiteLegacy
lock (ds)
{
- foreach (SceneObjectPart prim in obj.Children.Values)
+ lock (obj.Children)
{
-// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
- addPrim(prim, obj.UUID, regionUUID);
+ foreach (SceneObjectPart prim in obj.Children.Values)
+ {
+ // m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
+ addPrim(prim, obj.UUID, regionUUID);
+ }
}
}
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 365cdbb..847a999 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -406,7 +406,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
if (!m_scene.Permissions.CanRezObject(
- part.ParentGroup.Children.Count, remoteClient.AgentId, presence.AbsolutePosition))
+ part.ParentGroup.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
return;
presence.Appearance.DetachAttachment(itemID);
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index eef0c73..6decf54 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -526,7 +526,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
group.RootPart.CreateSelected = true;
if (!m_Scene.Permissions.CanRezObject(
- group.Children.Count, remoteClient.AgentId, pos)
+ group.PrimCount, remoteClient.AgentId, pos)
&& !attachment)
{
// The client operates in no fail mode. It will
@@ -594,7 +594,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
rootPart.Name = item.Name;
rootPart.Description = item.Description;
- List partList = new List(group.Children.Values);
+ List partList = null;
+ lock (group.Children)
+ partList = new List(group.Children.Values);
group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0)
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index bc653ce..1623e6e 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -243,36 +243,39 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// to the same scene (when this is possible).
sceneObject.ResetIDs();
- foreach (SceneObjectPart part in sceneObject.Children.Values)
+ lock (sceneObject.Children)
{
- if (!ResolveUserUuid(part.CreatorID))
- part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
-
- if (!ResolveUserUuid(part.OwnerID))
- part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
-
- if (!ResolveUserUuid(part.LastOwnerID))
- part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
-
- // And zap any troublesome sit target information
- part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
- part.SitTargetPosition = new Vector3(0, 0, 0);
-
- // Fix ownership/creator of inventory items
- // Not doing so results in inventory items
- // being no copy/no mod for everyone
- lock (part.TaskInventory)
+ foreach (SceneObjectPart part in sceneObject.Children.Values)
{
- TaskInventoryDictionary inv = part.TaskInventory;
- foreach (KeyValuePair kvp in inv)
+ if (!ResolveUserUuid(part.CreatorID))
+ part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
+
+ if (!ResolveUserUuid(part.OwnerID))
+ part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
+
+ if (!ResolveUserUuid(part.LastOwnerID))
+ part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
+
+ // And zap any troublesome sit target information
+ part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
+ part.SitTargetPosition = new Vector3(0, 0, 0);
+
+ // Fix ownership/creator of inventory items
+ // Not doing so results in inventory items
+ // being no copy/no mod for everyone
+ lock (part.TaskInventory)
{
- if (!ResolveUserUuid(kvp.Value.OwnerID))
- {
- kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
- }
- if (!ResolveUserUuid(kvp.Value.CreatorID))
+ TaskInventoryDictionary inv = part.TaskInventory;
+ foreach (KeyValuePair kvp in inv)
{
- kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
+ if (!ResolveUserUuid(kvp.Value.OwnerID))
+ {
+ kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
+ }
+ if (!ResolveUserUuid(kvp.Value.CreatorID))
+ {
+ kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
+ }
}
}
}
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
index 62abd4c..8ce6daf 100644
--- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
@@ -128,7 +128,10 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
group.SetOwnerId(remoteClient.AgentId);
group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId);
- List partList = new List(group.Children.Values);
+ List partList = null;
+
+ lock (group.Children)
+ partList = new List(group.Children.Values);
if (m_scene.Permissions.PropagatePermissions())
{
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs
index b96d95a..2f70c0a 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs
@@ -227,277 +227,281 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
{
SceneObjectGroup mapdot = (SceneObjectGroup)obj;
Color mapdotspot = Color.Gray; // Default color when prim color is white
+
// Loop over prim in group
- foreach (SceneObjectPart part in mapdot.Children.Values)
+ lock (mapdot.Children)
{
- if (part == null)
- continue;
-
- // Draw if the object is at least 1 meter wide in any direction
- if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f)
+ foreach (SceneObjectPart part in mapdot.Children.Values)
{
- // Try to get the RGBA of the default texture entry..
- //
- try
+ if (part == null)
+ continue;
+
+ // Draw if the object is at least 1 meter wide in any direction
+ if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f)
{
- // get the null checks out of the way
- // skip the ones that break
- if (part == null)
- continue;
-
- if (part.Shape == null)
- continue;
-
- if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass)
- continue; // eliminates trees from this since we don't really have a good tree representation
- // if you want tree blocks on the map comment the above line and uncomment the below line
- //mapdotspot = Color.PaleGreen;
-
- Primitive.TextureEntry textureEntry = part.Shape.Textures;
-
- if (textureEntry == null || textureEntry.DefaultTexture == null)
- continue;
-
- Color4 texcolor = textureEntry.DefaultTexture.RGBA;
-
- // Not sure why some of these are null, oh well.
-
- int colorr = 255 - (int)(texcolor.R * 255f);
- int colorg = 255 - (int)(texcolor.G * 255f);
- int colorb = 255 - (int)(texcolor.B * 255f);
-
- if (!(colorr == 255 && colorg == 255 && colorb == 255))
+ // Try to get the RGBA of the default texture entry..
+ //
+ try
{
- //Try to set the map spot color
- try
- {
- // If the color gets goofy somehow, skip it *shakes fist at Color4
- mapdotspot = Color.FromArgb(colorr, colorg, colorb);
- }
- catch (ArgumentException)
+ // get the null checks out of the way
+ // skip the ones that break
+ if (part == null)
+ continue;
+
+ if (part.Shape == null)
+ continue;
+
+ if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass)
+ continue; // eliminates trees from this since we don't really have a good tree representation
+ // if you want tree blocks on the map comment the above line and uncomment the below line
+ //mapdotspot = Color.PaleGreen;
+
+ Primitive.TextureEntry textureEntry = part.Shape.Textures;
+
+ if (textureEntry == null || textureEntry.DefaultTexture == null)
+ continue;
+
+ Color4 texcolor = textureEntry.DefaultTexture.RGBA;
+
+ // Not sure why some of these are null, oh well.
+
+ int colorr = 255 - (int)(texcolor.R * 255f);
+ int colorg = 255 - (int)(texcolor.G * 255f);
+ int colorb = 255 - (int)(texcolor.B * 255f);
+
+ if (!(colorr == 255 && colorg == 255 && colorb == 255))
{
+ //Try to set the map spot color
+ try
+ {
+ // If the color gets goofy somehow, skip it *shakes fist at Color4
+ mapdotspot = Color.FromArgb(colorr, colorg, colorb);
+ }
+ catch (ArgumentException)
+ {
+ }
}
}
- }
- catch (IndexOutOfRangeException)
- {
- // Windows Array
- }
- catch (ArgumentOutOfRangeException)
- {
- // Mono Array
- }
-
- Vector3 pos = part.GetWorldPosition();
-
- // skip prim outside of retion
- if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f)
- continue;
-
- // skip prim in non-finite position
- if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) ||
- Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y))
- continue;
-
- // Figure out if object is under 256m above the height of the terrain
- bool isBelow256AboveTerrain = false;
-
- try
- {
- isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f));
- }
- catch (Exception)
- {
- }
-
- if (isBelow256AboveTerrain)
- {
- // Translate scale by rotation so scale is represented properly when object is rotated
- Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z);
- Vector3 scale = new Vector3();
- Vector3 tScale = new Vector3();
- Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z);
-
- Quaternion llrot = part.GetWorldRotation();
- Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z);
- scale = lscale * rot;
-
- // negative scales don't work in this situation
- scale.X = Math.Abs(scale.X);
- scale.Y = Math.Abs(scale.Y);
- scale.Z = Math.Abs(scale.Z);
-
- // This scaling isn't very accurate and doesn't take into account the face rotation :P
- int mapdrawstartX = (int)(pos.X - scale.X);
- int mapdrawstartY = (int)(pos.Y - scale.Y);
- int mapdrawendX = (int)(pos.X + scale.X);
- int mapdrawendY = (int)(pos.Y + scale.Y);
-
- // If object is beyond the edge of the map, don't draw it to avoid errors
- if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1)
- || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0
- || mapdrawendY > ((int)Constants.RegionSize - 1))
+ catch (IndexOutOfRangeException)
+ {
+ // Windows Array
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ // Mono Array
+ }
+
+ Vector3 pos = part.GetWorldPosition();
+
+ // skip prim outside of retion
+ if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f)
continue;
-
-#region obb face reconstruction part duex
- Vector3[] vertexes = new Vector3[8];
-
- // float[] distance = new float[6];
- Vector3[] FaceA = new Vector3[6]; // vertex A for Facei
- Vector3[] FaceB = new Vector3[6]; // vertex B for Facei
- Vector3[] FaceC = new Vector3[6]; // vertex C for Facei
- Vector3[] FaceD = new Vector3[6]; // vertex D for Facei
-
- tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z);
- scale = ((tScale * rot));
- vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
- // vertexes[0].x = pos.X + vertexes[0].x;
- //vertexes[0].y = pos.Y + vertexes[0].y;
- //vertexes[0].z = pos.Z + vertexes[0].z;
-
- FaceA[0] = vertexes[0];
- FaceB[3] = vertexes[0];
- FaceA[4] = vertexes[0];
-
- tScale = lscale;
- scale = ((tScale * rot));
- vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
-
- // vertexes[1].x = pos.X + vertexes[1].x;
- // vertexes[1].y = pos.Y + vertexes[1].y;
- //vertexes[1].z = pos.Z + vertexes[1].z;
-
- FaceB[0] = vertexes[1];
- FaceA[1] = vertexes[1];
- FaceC[4] = vertexes[1];
-
- tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z);
- scale = ((tScale * rot));
-
- vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
-
- //vertexes[2].x = pos.X + vertexes[2].x;
- //vertexes[2].y = pos.Y + vertexes[2].y;
- //vertexes[2].z = pos.Z + vertexes[2].z;
-
- FaceC[0] = vertexes[2];
- FaceD[3] = vertexes[2];
- FaceC[5] = vertexes[2];
-
- tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z);
- scale = ((tScale * rot));
- vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
-
- //vertexes[3].x = pos.X + vertexes[3].x;
- // vertexes[3].y = pos.Y + vertexes[3].y;
- // vertexes[3].z = pos.Z + vertexes[3].z;
-
- FaceD[0] = vertexes[3];
- FaceC[1] = vertexes[3];
- FaceA[5] = vertexes[3];
-
- tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z);
- scale = ((tScale * rot));
- vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
-
- // vertexes[4].x = pos.X + vertexes[4].x;
- // vertexes[4].y = pos.Y + vertexes[4].y;
- // vertexes[4].z = pos.Z + vertexes[4].z;
-
- FaceB[1] = vertexes[4];
- FaceA[2] = vertexes[4];
- FaceD[4] = vertexes[4];
-
- tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z);
- scale = ((tScale * rot));
- vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
-
- // vertexes[5].x = pos.X + vertexes[5].x;
- // vertexes[5].y = pos.Y + vertexes[5].y;
- // vertexes[5].z = pos.Z + vertexes[5].z;
-
- FaceD[1] = vertexes[5];
- FaceC[2] = vertexes[5];
- FaceB[5] = vertexes[5];
-
- tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z);
- scale = ((tScale * rot));
- vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
-
- // vertexes[6].x = pos.X + vertexes[6].x;
- // vertexes[6].y = pos.Y + vertexes[6].y;
- // vertexes[6].z = pos.Z + vertexes[6].z;
-
- FaceB[2] = vertexes[6];
- FaceA[3] = vertexes[6];
- FaceB[4] = vertexes[6];
-
- tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z);
- scale = ((tScale * rot));
- vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
-
- // vertexes[7].x = pos.X + vertexes[7].x;
- // vertexes[7].y = pos.Y + vertexes[7].y;
- // vertexes[7].z = pos.Z + vertexes[7].z;
-
- FaceD[2] = vertexes[7];
- FaceC[3] = vertexes[7];
- FaceD[5] = vertexes[7];
-#endregion
-
- //int wy = 0;
-
- //bool breakYN = false; // If we run into an error drawing, break out of the
- // loop so we don't lag to death on error handling
- DrawStruct ds = new DrawStruct();
- ds.brush = new SolidBrush(mapdotspot);
- //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY);
-
- ds.trns = new face[FaceA.Length];
-
- for (int i = 0; i < FaceA.Length; i++)
+
+ // skip prim in non-finite position
+ if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) ||
+ Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y))
+ continue;
+
+ // Figure out if object is under 256m above the height of the terrain
+ bool isBelow256AboveTerrain = false;
+
+ try
{
- Point[] working = new Point[5];
- working[0] = project(FaceA[i], axPos);
- working[1] = project(FaceB[i], axPos);
- working[2] = project(FaceD[i], axPos);
- working[3] = project(FaceC[i], axPos);
- working[4] = project(FaceA[i], axPos);
-
- face workingface = new face();
- workingface.pts = working;
-
- ds.trns[i] = workingface;
+ isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f));
}
-
- z_sort.Add(part.LocalId, ds);
- z_localIDs.Add(part.LocalId);
- z_sortheights.Add(pos.Z);
-
- //for (int wx = mapdrawstartX; wx < mapdrawendX; wx++)
- //{
- //for (wy = mapdrawstartY; wy < mapdrawendY; wy++)
+ catch (Exception)
+ {
+ }
+
+ if (isBelow256AboveTerrain)
+ {
+ // Translate scale by rotation so scale is represented properly when object is rotated
+ Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z);
+ Vector3 scale = new Vector3();
+ Vector3 tScale = new Vector3();
+ Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z);
+
+ Quaternion llrot = part.GetWorldRotation();
+ Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z);
+ scale = lscale * rot;
+
+ // negative scales don't work in this situation
+ scale.X = Math.Abs(scale.X);
+ scale.Y = Math.Abs(scale.Y);
+ scale.Z = Math.Abs(scale.Z);
+
+ // This scaling isn't very accurate and doesn't take into account the face rotation :P
+ int mapdrawstartX = (int)(pos.X - scale.X);
+ int mapdrawstartY = (int)(pos.Y - scale.Y);
+ int mapdrawendX = (int)(pos.X + scale.X);
+ int mapdrawendY = (int)(pos.Y + scale.Y);
+
+ // If object is beyond the edge of the map, don't draw it to avoid errors
+ if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1)
+ || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0
+ || mapdrawendY > ((int)Constants.RegionSize - 1))
+ continue;
+
+ #region obb face reconstruction part duex
+ Vector3[] vertexes = new Vector3[8];
+
+ // float[] distance = new float[6];
+ Vector3[] FaceA = new Vector3[6]; // vertex A for Facei
+ Vector3[] FaceB = new Vector3[6]; // vertex B for Facei
+ Vector3[] FaceC = new Vector3[6]; // vertex C for Facei
+ Vector3[] FaceD = new Vector3[6]; // vertex D for Facei
+
+ tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z);
+ scale = ((tScale * rot));
+ vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
+ // vertexes[0].x = pos.X + vertexes[0].x;
+ //vertexes[0].y = pos.Y + vertexes[0].y;
+ //vertexes[0].z = pos.Z + vertexes[0].z;
+
+ FaceA[0] = vertexes[0];
+ FaceB[3] = vertexes[0];
+ FaceA[4] = vertexes[0];
+
+ tScale = lscale;
+ scale = ((tScale * rot));
+ vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
+
+ // vertexes[1].x = pos.X + vertexes[1].x;
+ // vertexes[1].y = pos.Y + vertexes[1].y;
+ //vertexes[1].z = pos.Z + vertexes[1].z;
+
+ FaceB[0] = vertexes[1];
+ FaceA[1] = vertexes[1];
+ FaceC[4] = vertexes[1];
+
+ tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z);
+ scale = ((tScale * rot));
+
+ vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
+
+ //vertexes[2].x = pos.X + vertexes[2].x;
+ //vertexes[2].y = pos.Y + vertexes[2].y;
+ //vertexes[2].z = pos.Z + vertexes[2].z;
+
+ FaceC[0] = vertexes[2];
+ FaceD[3] = vertexes[2];
+ FaceC[5] = vertexes[2];
+
+ tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z);
+ scale = ((tScale * rot));
+ vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
+
+ //vertexes[3].x = pos.X + vertexes[3].x;
+ // vertexes[3].y = pos.Y + vertexes[3].y;
+ // vertexes[3].z = pos.Z + vertexes[3].z;
+
+ FaceD[0] = vertexes[3];
+ FaceC[1] = vertexes[3];
+ FaceA[5] = vertexes[3];
+
+ tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z);
+ scale = ((tScale * rot));
+ vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
+
+ // vertexes[4].x = pos.X + vertexes[4].x;
+ // vertexes[4].y = pos.Y + vertexes[4].y;
+ // vertexes[4].z = pos.Z + vertexes[4].z;
+
+ FaceB[1] = vertexes[4];
+ FaceA[2] = vertexes[4];
+ FaceD[4] = vertexes[4];
+
+ tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z);
+ scale = ((tScale * rot));
+ vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
+
+ // vertexes[5].x = pos.X + vertexes[5].x;
+ // vertexes[5].y = pos.Y + vertexes[5].y;
+ // vertexes[5].z = pos.Z + vertexes[5].z;
+
+ FaceD[1] = vertexes[5];
+ FaceC[2] = vertexes[5];
+ FaceB[5] = vertexes[5];
+
+ tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z);
+ scale = ((tScale * rot));
+ vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
+
+ // vertexes[6].x = pos.X + vertexes[6].x;
+ // vertexes[6].y = pos.Y + vertexes[6].y;
+ // vertexes[6].z = pos.Z + vertexes[6].z;
+
+ FaceB[2] = vertexes[6];
+ FaceA[3] = vertexes[6];
+ FaceB[4] = vertexes[6];
+
+ tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z);
+ scale = ((tScale * rot));
+ vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
+
+ // vertexes[7].x = pos.X + vertexes[7].x;
+ // vertexes[7].y = pos.Y + vertexes[7].y;
+ // vertexes[7].z = pos.Z + vertexes[7].z;
+
+ FaceD[2] = vertexes[7];
+ FaceC[3] = vertexes[7];
+ FaceD[5] = vertexes[7];
+ #endregion
+
+ //int wy = 0;
+
+ //bool breakYN = false; // If we run into an error drawing, break out of the
+ // loop so we don't lag to death on error handling
+ DrawStruct ds = new DrawStruct();
+ ds.brush = new SolidBrush(mapdotspot);
+ //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY);
+
+ ds.trns = new face[FaceA.Length];
+
+ for (int i = 0; i < FaceA.Length; i++)
+ {
+ Point[] working = new Point[5];
+ working[0] = project(FaceA[i], axPos);
+ working[1] = project(FaceB[i], axPos);
+ working[2] = project(FaceD[i], axPos);
+ working[3] = project(FaceC[i], axPos);
+ working[4] = project(FaceA[i], axPos);
+
+ face workingface = new face();
+ workingface.pts = working;
+
+ ds.trns[i] = workingface;
+ }
+
+ z_sort.Add(part.LocalId, ds);
+ z_localIDs.Add(part.LocalId);
+ z_sortheights.Add(pos.Z);
+
+ //for (int wx = mapdrawstartX; wx < mapdrawendX; wx++)
//{
- //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy);
- //try
+ //for (wy = mapdrawstartY; wy < mapdrawendY; wy++)
//{
- // Remember, flip the y!
- // mapbmp.SetPixel(wx, (255 - wy), mapdotspot);
+ //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy);
+ //try
+ //{
+ // Remember, flip the y!
+ // mapbmp.SetPixel(wx, (255 - wy), mapdotspot);
+ //}
+ //catch (ArgumentException)
+ //{
+ // breakYN = true;
+ //}
+
+ //if (breakYN)
+ // break;
//}
- //catch (ArgumentException)
- //{
- // breakYN = true;
- //}
-
+
//if (breakYN)
// break;
//}
-
- //if (breakYN)
- // break;
- //}
- } // Object is within 256m Z of terrain
- } // object is at least a meter wide
+ } // Object is within 256m Z of terrain
+ } // object is at least a meter wide
+ } // mapdot.Children lock
} // loop over group children
} // entitybase is sceneobject group
} // foreach loop over entities
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
if (null == group)
return null;
- if (!Permissions.CanRezObject(group.Children.Count, item.OwnerID, pos))
+ if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos))
return null;
if (!Permissions.BypassPermissions())
@@ -2051,8 +2051,11 @@ namespace OpenSim.Region.Framework.Scenes
sog.SetGroup(groupID, remoteClient);
sog.ScheduleGroupForFullUpdate();
- foreach (SceneObjectPart child in sog.Children.Values)
- child.Inventory.ChangeInventoryOwner(ownerID);
+ lock (sog.Children)
+ {
+ foreach (SceneObjectPart child in sog.Children.Values)
+ child.Inventory.ChangeInventoryOwner(ownerID);
+ }
}
else
{
@@ -2062,16 +2065,18 @@ namespace OpenSim.Region.Framework.Scenes
if (sog.GroupID != groupID)
continue;
- foreach (SceneObjectPart child in sog.Children.Values)
+ lock (sog.Children)
{
- child.LastOwnerID = child.OwnerID;
- child.Inventory.ChangeInventoryOwner(groupID);
+ foreach (SceneObjectPart child in sog.Children.Values)
+ {
+ child.LastOwnerID = child.OwnerID;
+ child.Inventory.ChangeInventoryOwner(groupID);
+ }
}
sog.SetOwnerId(groupID);
sog.ApplyNextOwnerPermissions();
- }
-
+ }
}
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
}
break;
}
- else
- {
- // We also need to check the children of this prim as they
- // can be selected as well and send property information
- bool foundPrim = false;
- foreach (KeyValuePair child in ((SceneObjectGroup) ent).Children)
- {
- if (child.Value.LocalId == primLocalID)
- {
- child.Value.GetProperties(remoteClient);
- foundPrim = true;
- break;
- }
- }
- if (foundPrim) break;
+ else
+ {
+ // We also need to check the children of this prim as they
+ // can be selected as well and send property information
+ bool foundPrim = false;
+
+ SceneObjectGroup sog = ent as SceneObjectGroup;
+
+ lock (sog.Children)
+ {
+ foreach (KeyValuePair child in (sog.Children))
+ {
+ if (child.Value.LocalId == primLocalID)
+ {
+ child.Value.GetProperties(remoteClient);
+ foundPrim = true;
+ break;
+ }
+ }
+ }
+
+ if (foundPrim)
+ break;
}
}
}
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
if (group.RootPart == null)
{
- m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
- group.Children == null ? 0 : group.Children.Count);
+ m_log.ErrorFormat(
+ "[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
+ group.Children == null ? 0 : group.PrimCount);
}
AddRestoredSceneObject(group, true, true);
@@ -2064,18 +2065,22 @@ namespace OpenSim.Region.Framework.Scenes
group.RemoveScriptInstances(true);
}
- foreach (SceneObjectPart part in group.Children.Values)
+ lock (group.Children)
{
- if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
+ foreach (SceneObjectPart part in group.Children.Values)
{
- PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
- }
- else if (part.PhysActor != null)
- {
- PhysicsScene.RemovePrim(part.PhysActor);
- part.PhysActor = null;
+ if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
+ {
+ PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
+ }
+ else if (part.PhysActor != null)
+ {
+ PhysicsScene.RemovePrim(part.PhysActor);
+ part.PhysActor = null;
+ }
}
}
+
// if (rootPart.PhysActor != null)
// {
// PhysicsScene.RemovePrim(rootPart.PhysActor);
@@ -2426,14 +2431,16 @@ namespace OpenSim.Region.Framework.Scenes
// Force allocation of new LocalId
//
- foreach (SceneObjectPart p in sceneObject.Children.Values)
- p.LocalId = 0;
+ lock (sceneObject.Children)
+ {
+ foreach (SceneObjectPart p in sceneObject.Children.Values)
+ p.LocalId = 0;
+ }
if (sceneObject.IsAttachmentCheckFull()) // Attachment
{
sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
-
// Don't sent a full update here because this will cause full updates to be sent twice for
// attachments on region crossings, resulting in viewer glitches.
@@ -2447,7 +2454,6 @@ namespace OpenSim.Region.Framework.Scenes
if (sp != null)
{
-
SceneObjectGroup grp = sceneObject;
m_log.DebugFormat(
@@ -2459,7 +2465,6 @@ namespace OpenSim.Region.Framework.Scenes
if (AttachmentsModule != null)
AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false);
-
}
else
{
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
// "[SCENE GRAPH]: Adding object {0} {1} to region {2}",
// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
- if (m_parentScene.m_clampPrimSize)
+ lock (sceneObject.Children)
{
- foreach (SceneObjectPart part in sceneObject.Children.Values)
+ if (m_parentScene.m_clampPrimSize)
{
- Vector3 scale = part.Shape.Scale;
-
- if (scale.X > m_parentScene.m_maxNonphys)
- scale.X = m_parentScene.m_maxNonphys;
- if (scale.Y > m_parentScene.m_maxNonphys)
- scale.Y = m_parentScene.m_maxNonphys;
- if (scale.Z > m_parentScene.m_maxNonphys)
- scale.Z = m_parentScene.m_maxNonphys;
-
- part.Shape.Scale = scale;
+ foreach (SceneObjectPart part in sceneObject.Children.Values)
+ {
+ Vector3 scale = part.Shape.Scale;
+
+ if (scale.X > m_parentScene.m_maxNonphys)
+ scale.X = m_parentScene.m_maxNonphys;
+ if (scale.Y > m_parentScene.m_maxNonphys)
+ scale.Y = m_parentScene.m_maxNonphys;
+ if (scale.Z > m_parentScene.m_maxNonphys)
+ scale.Z = m_parentScene.m_maxNonphys;
+
+ part.Shape.Scale = scale;
+ }
}
- }
+
+ sceneObject.AttachToScene(m_parentScene);
+
+ if (sendClientUpdates)
+ sceneObject.ScheduleGroupForFullUpdate();
+
+ Entities.Add(sceneObject);
+ m_numPrim += sceneObject.Children.Count;
- sceneObject.AttachToScene(m_parentScene);
+ if (attachToBackup)
+ sceneObject.AttachToBackup();
- if (sendClientUpdates)
- sceneObject.ScheduleGroupForFullUpdate();
-
- Entities.Add(sceneObject);
- m_numPrim += sceneObject.Children.Count;
-
- if (attachToBackup)
- sceneObject.AttachToBackup();
-
- if (OnObjectCreate != null)
- OnObjectCreate(sceneObject);
-
- lock (m_dictionary_lock)
- {
- SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
- SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
- foreach (SceneObjectPart part in sceneObject.Children.Values)
+ if (OnObjectCreate != null)
+ OnObjectCreate(sceneObject);
+
+ lock (m_dictionary_lock)
{
- SceneObjectGroupsByFullID[part.UUID] = sceneObject;
- SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
+ SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
+ SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
+ foreach (SceneObjectPart part in sceneObject.Children.Values)
+ {
+ SceneObjectGroupsByFullID[part.UUID] = sceneObject;
+ SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
+ }
}
}
}
@@ -420,11 +423,16 @@ namespace OpenSim.Region.Framework.Scenes
{
if (!resultOfObjectLinked)
{
- m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count;
-
- if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
+ SceneObjectGroup sog = Entities[uuid] as SceneObjectGroup;
+
+ lock (sog.Children)
{
- RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count);
+ m_numPrim -= sog.PrimCount;
+
+ if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
+ {
+ RemovePhysicalPrim(sog.PrimCount);
+ }
}
}
@@ -1603,7 +1611,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (part != null)
{
- if (part.ParentGroup.Children.Count != 1) // Skip single
+ if (part.ParentGroup.PrimCount != 1) // Skip single
{
if (part.LinkNum < 2) // Root
rootParts.Add(part);
@@ -1631,8 +1639,15 @@ namespace OpenSim.Region.Framework.Scenes
// However, editing linked parts and unlinking may be different
//
SceneObjectGroup group = root.ParentGroup;
- List newSet = new List(group.Children.Values);
- int numChildren = group.Children.Count;
+
+ List newSet = null;
+ int numChildren = -1;
+
+ lock (group.Children)
+ {
+ newSet = new List(group.Children.Values);
+ numChildren = group.PrimCount;
+ }
// If there are prims left in a link set, but the root is
// slated for unlink, we need to do this
@@ -1711,12 +1726,17 @@ namespace OpenSim.Region.Framework.Scenes
{
if (ent is SceneObjectGroup)
{
- foreach (KeyValuePair subent in ((SceneObjectGroup)ent).Children)
+ SceneObjectGroup sog = ent as SceneObjectGroup;
+
+ lock (sog.Children)
{
- if (subent.Value.LocalId == localID)
+ foreach (KeyValuePair subent in sog.Children)
{
- objid = subent.Key;
- obj = subent.Value;
+ if (subent.Value.LocalId == localID)
+ {
+ objid = subent.Key;
+ obj = subent.Value;
+ }
}
}
}
@@ -1781,7 +1801,8 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectGroup original = GetGroupByPrim(originalPrimID);
if (original != null)
{
- if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition))
+ if (m_parentScene.Permissions.CanDuplicateObject(
+ original.PrimCount, original.UUID, AgentID, original.AbsolutePosition))
{
SceneObjectGroup copy = original.Copy(true);
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
///
public int PrimCount
{
- get { return m_parts.Count; }
+ get { lock (m_parts) { return m_parts.Count; } }
}
protected Quaternion m_rotation = Quaternion.Identity;
@@ -237,6 +237,7 @@ namespace OpenSim.Region.Framework.Scenes
///
/// The parts of this scene object group. You must lock this property before using it.
+ /// If you want to know the number of children, consider using the PrimCount property instead
///
public Dictionary Children
{
@@ -298,6 +299,7 @@ namespace OpenSim.Region.Framework.Scenes
{
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
}
+
if (RootPart.GetStatusSandbox())
{
if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
@@ -308,6 +310,7 @@ namespace OpenSim.Region.Framework.Scenes
return;
}
}
+
lock (m_parts)
{
foreach (SceneObjectPart part in m_parts.Values)
@@ -558,21 +561,23 @@ namespace OpenSim.Region.Framework.Scenes
if (m_rootPart.LocalId == 0)
m_rootPart.LocalId = m_scene.AllocateLocalId();
- // No need to lock here since the object isn't yet in a scene
- foreach (SceneObjectPart part in m_parts.Values)
+ lock (m_parts)
{
- if (Object.ReferenceEquals(part, m_rootPart))
- {
- continue;
- }
-
- if (part.LocalId == 0)
+ foreach (SceneObjectPart part in m_parts.Values)
{
- part.LocalId = m_scene.AllocateLocalId();
+ if (Object.ReferenceEquals(part, m_rootPart))
+ {
+ continue;
+ }
+
+ if (part.LocalId == 0)
+ {
+ part.LocalId = m_scene.AllocateLocalId();
+ }
+
+ part.ParentID = m_rootPart.LocalId;
+ //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);
}
-
- part.ParentID = m_rootPart.LocalId;
- //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);
}
ApplyPhysics(m_scene.m_physicalPrim);
@@ -670,7 +675,7 @@ namespace OpenSim.Region.Framework.Scenes
minY = 256f;
minZ = 8192f;
- lock(m_parts);
+ lock(m_parts)
{
foreach (SceneObjectPart part in m_parts.Values)
{
@@ -995,9 +1000,12 @@ namespace OpenSim.Region.Framework.Scenes
m_rootPart.AttachedAvatar = agentID;
//Anakin Lohner bug #3839
- foreach (SceneObjectPart p in m_parts.Values)
+ lock (m_parts)
{
- p.AttachedAvatar = agentID;
+ foreach (SceneObjectPart p in m_parts.Values)
+ {
+ p.AttachedAvatar = agentID;
+ }
}
if (m_rootPart.PhysActor != null)
@@ -1065,10 +1073,14 @@ namespace OpenSim.Region.Framework.Scenes
AbsolutePosition = detachedpos;
m_rootPart.AttachedAvatar = UUID.Zero;
- //Anakin Lohner bug #3839
- foreach (SceneObjectPart p in m_parts.Values)
+
+ //Anakin Lohner bug #3839
+ lock (m_parts)
{
- p.AttachedAvatar = UUID.Zero;
+ foreach (SceneObjectPart p in m_parts.Values)
+ {
+ p.AttachedAvatar = UUID.Zero;
+ }
}
m_rootPart.SetParentLocalId(0);
@@ -1094,10 +1106,14 @@ namespace OpenSim.Region.Framework.Scenes
}
m_rootPart.AttachedAvatar = UUID.Zero;
+
//Anakin Lohner bug #3839
- foreach (SceneObjectPart p in m_parts.Values)
+ lock (m_parts)
{
- p.AttachedAvatar = UUID.Zero;
+ foreach (SceneObjectPart p in m_parts.Values)
+ {
+ p.AttachedAvatar = UUID.Zero;
+ }
}
m_rootPart.SetParentLocalId(0);
@@ -1160,9 +1176,8 @@ namespace OpenSim.Region.Framework.Scenes
part.ParentID = 0;
part.LinkNum = 0;
- // No locking required since the SOG should not be in the scene yet - one can't change root parts after
- // the scene object has been attached to the scene
- m_parts.Add(m_rootPart.UUID, m_rootPart);
+ lock (m_parts)
+ m_parts.Add(m_rootPart.UUID, m_rootPart);
}
///
@@ -1625,7 +1640,7 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- ///
+ /// Copy the given part as the root part of this scene object.
///
///
///
@@ -1882,11 +1897,12 @@ namespace OpenSim.Region.Framework.Scenes
///
public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
{
- SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
- newPart.SetParent(this);
-
+ SceneObjectPart newPart = null;
+
lock (m_parts)
- {
+ {
+ newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
+ newPart.SetParent(this);
m_parts.Add(newPart.UUID, newPart);
}
@@ -1903,14 +1919,15 @@ namespace OpenSim.Region.Framework.Scenes
///
public void ResetIDs()
{
- // As this is only ever called for prims which are not currently part of the scene (and hence
- // not accessible by clients), there should be no need to lock
- List partsList = new List(m_parts.Values);
- m_parts.Clear();
- foreach (SceneObjectPart part in partsList)
+ lock (m_parts)
{
- part.ResetIDs(part.LinkNum); // Don't change link nums
- m_parts.Add(part.UUID, part);
+ List partsList = new List(m_parts.Values);
+ m_parts.Clear();
+ foreach (SceneObjectPart part in partsList)
+ {
+ part.ResetIDs(part.LinkNum); // Don't change link nums
+ m_parts.Add(part.UUID, part);
+ }
}
}
@@ -2136,10 +2153,15 @@ namespace OpenSim.Region.Framework.Scenes
public SceneObjectPart GetChildPart(UUID primID)
{
SceneObjectPart childPart = null;
- if (m_parts.ContainsKey(primID))
+
+ lock (m_parts)
{
- childPart = m_parts[primID];
+ if (m_parts.ContainsKey(primID))
+ {
+ childPart = m_parts[primID];
+ }
}
+
return childPart;
}
@@ -2174,9 +2196,10 @@ namespace OpenSim.Region.Framework.Scenes
///
public bool HasChildPrim(UUID primID)
{
- if (m_parts.ContainsKey(primID))
+ lock (m_parts)
{
- return true;
+ if (m_parts.ContainsKey(primID))
+ return true;
}
return false;
@@ -2370,17 +2393,19 @@ namespace OpenSim.Region.Framework.Scenes
lock (m_parts)
{
m_parts.Remove(linkPart.UUID);
- }
-
- if (m_parts.Count == 1 && RootPart != null) //Single prim is left
- RootPart.LinkNum = 0;
- else
- {
- foreach (SceneObjectPart p in m_parts.Values)
+
+ if (m_parts.Count == 1 && RootPart != null) //Single prim is left
{
- if (p.LinkNum > linkPart.LinkNum)
- p.LinkNum--;
+ RootPart.LinkNum = 0;
}
+ else
+ {
+ foreach (SceneObjectPart p in m_parts.Values)
+ {
+ if (p.LinkNum > linkPart.LinkNum)
+ p.LinkNum--;
+ }
+ }
}
linkPart.ParentID = 0;
@@ -2762,9 +2787,11 @@ namespace OpenSim.Region.Framework.Scenes
public void UpdatePermissions(UUID AgentID, byte field, uint localID,
uint mask, byte addRemTF)
{
- foreach (SceneObjectPart part in m_parts.Values)
- part.UpdatePermissions(AgentID, field, localID, mask,
- addRemTF);
+ lock (m_parts)
+ {
+ foreach (SceneObjectPart part in m_parts.Values)
+ part.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
+ }
HasGroupChanged = true;
}
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
rootPart.Name = item.Name;
rootPart.Description = item.Description;
- List partList = new List(group.Children.Values);
+ List partList = null;
+
+ lock (group.Children)
+ partList = new List(group.Children.Values);
group.SetGroup(m_part.GroupID, null);
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
index 56656fc..de1e01c 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
@@ -121,16 +121,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
continue;
temp = (SceneObjectGroup) currObj;
- if (m_CMEntityHash.ContainsKey(temp.UUID))
+ lock (temp.Children)
{
- foreach (SceneObjectPart part in temp.Children.Values)
- if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID))
+ if (m_CMEntityHash.ContainsKey(temp.UUID))
+ {
+ foreach (SceneObjectPart part in temp.Children.Values)
+ if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID))
+ missingList.Add(part);
+ }
+ else //Entire group is missing from revision. (and is a new part in region)
+ {
+ foreach (SceneObjectPart part in temp.Children.Values)
missingList.Add(part);
- }
- else //Entire group is missing from revision. (and is a new part in region)
- {
- foreach (SceneObjectPart part in temp.Children.Values)
- missingList.Add(part);
+ }
}
}
return missingList;
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
index 0dc78c0..e5fcb54 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -167,9 +167,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
{
// Deal with new parts not revisioned that have been deleted.
- foreach (SceneObjectPart part in group.Children.Values)
- if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
- m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID);
+ lock (group.Children)
+ {
+ foreach (SceneObjectPart part in group.Children.Values)
+ if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
+ m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID);
+ }
}
///
@@ -207,8 +210,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
{
temp = SceneObjectSerializer.FromXml2Format(xml);
temp.SetScene(scene);
- foreach (SceneObjectPart part in temp.Children.Values)
- part.RegionHandle = scene.RegionInfo.RegionHandle;
+
+ lock (temp.Children)
+ {
+ foreach (SceneObjectPart part in temp.Children.Values)
+ part.RegionHandle = scene.RegionInfo.RegionHandle;
+ }
+
ReplacementList.Add(temp.UUID, (EntityBase)temp);
}
catch (Exception e)
@@ -338,15 +346,20 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
System.Collections.ArrayList auraList = new System.Collections.ArrayList();
if (group == null)
return null;
- foreach (SceneObjectPart part in group.Children.Values)
+
+ lock (group.Children)
{
- if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
+ foreach (SceneObjectPart part in group.Children.Values)
{
- ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale);
- ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
- auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
+ if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
+ {
+ ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale);
+ ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
+ auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
+ }
}
}
+
return auraList;
}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
index 46fbd39..f75f40a 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
@@ -186,9 +186,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll();
// Deal with new parts not revisioned that have been deleted.
- foreach (SceneObjectPart part in group.Children.Values)
- if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
- ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
+ lock (group.Children)
+ {
+ foreach (SceneObjectPart part in group.Children.Values)
+ if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
+ ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
+ }
}
public void SendMetaEntitiesToNewClient(IClientAPI client)
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
index ada6701..2730eee 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -132,30 +132,33 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
// if group is not contained in scene's list
if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
{
- foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
+ lock (m_UnchangedEntity.Children)
{
- // if scene list no longer contains this part, display translucent part and mark with red aura
- if (!ContainsKey(sceneEntityList, part.UUID))
+ foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
{
- // if already displaying a red aura over part, make sure its red
- if (m_AuraEntities.ContainsKey(part.UUID))
- {
- m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale);
- }
- else
+ // if scene list no longer contains this part, display translucent part and mark with red aura
+ if (!ContainsKey(sceneEntityList, part.UUID))
{
- AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
- part.GetWorldPosition(),
- MetaEntity.TRANSLUCENT,
- new Vector3(254,0,0),
- part.Scale
- );
- m_AuraEntities.Add(part.UUID, auraGroup);
+ // if already displaying a red aura over part, make sure its red
+ if (m_AuraEntities.ContainsKey(part.UUID))
+ {
+ m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale);
+ }
+ else
+ {
+ AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
+ part.GetWorldPosition(),
+ MetaEntity.TRANSLUCENT,
+ new Vector3(254,0,0),
+ part.Scale
+ );
+ m_AuraEntities.Add(part.UUID, auraGroup);
+ }
+ SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
+ SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
}
- SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
- SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
+ // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
}
- // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
}
// a deleted part has no where to point a beam particle system,
@@ -180,8 +183,10 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
///
public bool HasChildPrim(UUID uuid)
{
- if (m_UnchangedEntity.Children.ContainsKey(uuid))
- return true;
+ lock (m_UnchangedEntity.Children)
+ if (m_UnchangedEntity.Children.ContainsKey(uuid))
+ return true;
+
return false;
}
@@ -190,9 +195,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
///
public bool HasChildPrim(uint localID)
{
- foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
- if (part.LocalId == localID)
- return true;
+ lock (m_UnchangedEntity.Children)
+ {
+ foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
+ if (part.LocalId == localID)
+ return true;
+ }
+
return false;
}
@@ -228,37 +237,72 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
// Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
// had originally saved.
// m_Entity will NOT necessarily be the same entity as the user had saved.
- foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values)
+ lock (m_UnchangedEntity.Children)
{
- //This is the part that we use to show changes.
- metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
- if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
+ foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values)
{
- sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID];
- differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
- if (differences != Diff.NONE)
- metaEntityPart.Text = "CHANGE: " + differences.ToString();
- if (differences != 0)
+ //This is the part that we use to show changes.
+ metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
+ if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
{
- // Root Part that has been modified
- if ((differences&Diff.POSITION) > 0)
+ sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID];
+ differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
+ if (differences != Diff.NONE)
+ metaEntityPart.Text = "CHANGE: " + differences.ToString();
+ if (differences != 0)
+ {
+ // Root Part that has been modified
+ if ((differences&Diff.POSITION) > 0)
+ {
+ // If the position of any part has changed, make sure the RootPart of the
+ // meta entity is pointing with a beam particle system
+ if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
+ {
+ m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
+ m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
+ }
+ BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
+ m_UnchangedEntity.RootPart.GetWorldPosition(),
+ MetaEntity.TRANSLUCENT,
+ sceneEntityPart,
+ new Vector3(0,0,254)
+ );
+ m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
+ }
+
+ if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
+ {
+ m_AuraEntities[UnchangedPart.UUID].HideFromAll();
+ m_AuraEntities.Remove(UnchangedPart.UUID);
+ }
+ AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
+ UnchangedPart.GetWorldPosition(),
+ MetaEntity.TRANSLUCENT,
+ new Vector3(0,0,254),
+ UnchangedPart.Scale
+ );
+ m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
+ SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
+
+ DiffersFromSceneGroup = true;
+ }
+ else // no differences between scene part and meta part
{
- // If the position of any part has changed, make sure the RootPart of the
- // meta entity is pointing with a beam particle system
if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
{
m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
}
- BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
- m_UnchangedEntity.RootPart.GetWorldPosition(),
- MetaEntity.TRANSLUCENT,
- sceneEntityPart,
- new Vector3(0,0,254)
- );
- m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
+ if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
+ {
+ m_AuraEntities[UnchangedPart.UUID].HideFromAll();
+ m_AuraEntities.Remove(UnchangedPart.UUID);
+ }
+ SetPartTransparency(metaEntityPart, MetaEntity.NONE);
}
-
+ }
+ else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
+ {
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
{
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
@@ -267,48 +311,17 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
UnchangedPart.GetWorldPosition(),
MetaEntity.TRANSLUCENT,
- new Vector3(0,0,254),
+ new Vector3(254,0,0),
UnchangedPart.Scale
);
m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
-
+
DiffersFromSceneGroup = true;
}
- else // no differences between scene part and meta part
- {
- if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
- {
- m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
- m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
- }
- if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
- {
- m_AuraEntities[UnchangedPart.UUID].HideFromAll();
- m_AuraEntities.Remove(UnchangedPart.UUID);
- }
- SetPartTransparency(metaEntityPart, MetaEntity.NONE);
- }
- }
- else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
- {
- if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
- {
- m_AuraEntities[UnchangedPart.UUID].HideFromAll();
- m_AuraEntities.Remove(UnchangedPart.UUID);
- }
- AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
- UnchangedPart.GetWorldPosition(),
- MetaEntity.TRANSLUCENT,
- new Vector3(254,0,0),
- UnchangedPart.Scale
- );
- m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
- SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
-
- DiffersFromSceneGroup = true;
}
}
+
return changed;
}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
index 841ee00..796f437 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
@@ -150,15 +150,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
{
//make new uuids
Dictionary parts = new Dictionary();
- foreach (SceneObjectPart part in m_Entity.Children.Values)
+
+ lock (m_Entity.Children)
{
- part.ResetIDs(part.LinkNum);
- parts.Add(part.UUID, part);
+ foreach (SceneObjectPart part in m_Entity.Children.Values)
+ {
+ part.ResetIDs(part.LinkNum);
+ parts.Add(part.UUID, part);
+ }
+
+ //finalize
+ m_Entity.RootPart.PhysActor = null;
+ m_Entity.Children = parts;
}
-
- //finalize
- m_Entity.RootPart.PhysActor = null;
- m_Entity.Children = parts;
}
#endregion Protected Methods
@@ -173,8 +177,11 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
//This deletes the group without removing from any databases.
//This is important because we are not IN any database.
//m_Entity.FakeDeleteGroup();
- foreach (SceneObjectPart part in m_Entity.Children.Values)
- client.SendKillObject(m_Entity.RegionHandle, part.LocalId);
+ lock (m_Entity.Children)
+ {
+ foreach (SceneObjectPart part in m_Entity.Children.Values)
+ client.SendKillObject(m_Entity.RegionHandle, part.LocalId);
+ }
}
///
@@ -182,12 +189,15 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
///
public virtual void HideFromAll()
{
- foreach (SceneObjectPart part in m_Entity.Children.Values)
+ lock (m_Entity.Children)
{
- m_Entity.Scene.ForEachClient(
- delegate(IClientAPI controller)
- { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); }
- );
+ foreach (SceneObjectPart part in m_Entity.Children.Values)
+ {
+ m_Entity.Scene.ForEachClient(
+ delegate(IClientAPI controller)
+ { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); }
+ );
+ }
}
}
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs
index 96cccb7..34171b0 100644
--- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs
@@ -185,14 +185,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
get
{
SceneObjectPart my = GetSOP();
- int total = my.ParentGroup.Children.Count;
-
- IObject[] rets = new IObject[total];
-
- int i = 0;
- foreach (KeyValuePair pair in my.ParentGroup.Children)
+ IObject[] rets = null;
+
+ lock (my.ParentGroup.Children)
{
- rets[i++] = new SOPObject(m_rootScene, pair.Value.LocalId, m_security);
+ int total = my.ParentGroup.Children.Count;
+
+ rets = new IObject[total];
+
+ int i = 0;
+ foreach (KeyValuePair pair in my.ParentGroup.Children)
+ {
+ rets[i++] = new SOPObject(m_rootScene, pair.Value.LocalId, m_security);
+ }
}
return rets;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 21604d0..af42dae 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -235,7 +235,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
case ScriptBaseClass.LINK_SET:
if (m_host.ParentGroup != null)
- return new List(m_host.ParentGroup.Children.Values);
+ {
+ lock (m_host.ParentGroup.Children)
+ return new List(m_host.ParentGroup.Children.Values);
+ }
return ret;
case ScriptBaseClass.LINK_ROOT:
@@ -250,7 +253,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case ScriptBaseClass.LINK_ALL_OTHERS:
if (m_host.ParentGroup == null)
return new List();
- ret = new List(m_host.ParentGroup.Children.Values);
+
+ lock (m_host.ParentGroup.Children)
+ ret = new List(m_host.ParentGroup.Children.Values);
+
if (ret.Contains(m_host))
ret.Remove(m_host);
return ret;
@@ -258,7 +264,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case ScriptBaseClass.LINK_ALL_CHILDREN:
if (m_host.ParentGroup == null)
return new List();
- ret = new List(m_host.ParentGroup.Children.Values);
+
+ lock (m_host.ParentGroup.Children)
+ ret = new List(m_host.ParentGroup.Children.Values);
+
if (ret.Contains(m_host.ParentGroup.RootPart))
ret.Remove(m_host.ParentGroup.RootPart);
return ret;
@@ -1178,12 +1187,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (group == null)
return;
bool allow = true;
- foreach (SceneObjectPart part in group.Children.Values)
+
+ lock (group.Children)
{
- if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys)
+ foreach (SceneObjectPart part in group.Children.Values)
{
- allow = false;
- break;
+ if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys)
+ {
+ allow = false;
+ break;
+ }
}
}
@@ -3492,7 +3505,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
- if (m_host.ParentGroup.Children.Count > 1)
+ if (m_host.ParentGroup.PrimCount > 1)
{
return m_host.LinkNum;
}
@@ -3604,15 +3617,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case ScriptBaseClass.LINK_ALL_OTHERS:
case ScriptBaseClass.LINK_ALL_CHILDREN:
case ScriptBaseClass.LINK_THIS:
- foreach (SceneObjectPart part in parentPrim.Children.Values)
+ lock (parentPrim.Children)
{
- if (part.UUID != m_host.UUID)
+ foreach (SceneObjectPart part in parentPrim.Children.Values)
{
- childPrim = part;
- break;
+ if (part.UUID != m_host.UUID)
+ {
+ childPrim = part;
+ break;
+ }
}
+ break;
}
- break;
default:
childPrim = parentPrim.GetLinkNumPart(linknum);
if (childPrim.UUID == m_host.UUID)
@@ -3623,27 +3639,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (linknum == ScriptBaseClass.LINK_ROOT)
{
// Restructuring Multiple Prims.
- List parts = new List(parentPrim.Children.Values);
- parts.Remove(parentPrim.RootPart);
- foreach (SceneObjectPart part in parts)
- {
- parentPrim.DelinkFromGroup(part.LocalId, true);
- }
- parentPrim.HasGroupChanged = true;
- parentPrim.ScheduleGroupForFullUpdate();
- parentPrim.TriggerScriptChangedEvent(Changed.LINK);
-
- if (parts.Count > 0)
+ lock (parentPrim.Children)
{
- SceneObjectPart newRoot = parts[0];
- parts.Remove(newRoot);
+ List parts = new List(parentPrim.Children.Values);
+ parts.Remove(parentPrim.RootPart);
foreach (SceneObjectPart part in parts)
{
- part.UpdateFlag = 0;
- newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
+ parentPrim.DelinkFromGroup(part.LocalId, true);
+ }
+ parentPrim.HasGroupChanged = true;
+ parentPrim.ScheduleGroupForFullUpdate();
+ parentPrim.TriggerScriptChangedEvent(Changed.LINK);
+
+ if (parts.Count > 0)
+ {
+ SceneObjectPart newRoot = parts[0];
+ parts.Remove(newRoot);
+ foreach (SceneObjectPart part in parts)
+ {
+ part.UpdateFlag = 0;
+ newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
+ }
+ newRoot.ParentGroup.HasGroupChanged = true;
+ newRoot.ParentGroup.ScheduleGroupForFullUpdate();
}
- newRoot.ParentGroup.HasGroupChanged = true;
- newRoot.ParentGroup.ScheduleGroupForFullUpdate();
}
}
else
@@ -3665,16 +3684,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (parentPrim.RootPart.AttachmentPoint != 0)
return; // Fail silently if attached
- List parts = new List(parentPrim.Children.Values);
- parts.Remove(parentPrim.RootPart);
-
- foreach (SceneObjectPart part in parts)
+ lock (parentPrim.Children)
{
- parentPrim.DelinkFromGroup(part.LocalId, true);
- parentPrim.TriggerScriptChangedEvent(Changed.LINK);
+ List parts = new List(parentPrim.Children.Values);
+ parts.Remove(parentPrim.RootPart);
+
+ foreach (SceneObjectPart part in parts)
+ {
+ parentPrim.DelinkFromGroup(part.LocalId, true);
+ parentPrim.TriggerScriptChangedEvent(Changed.LINK);
+ }
+ parentPrim.HasGroupChanged = true;
+ parentPrim.ScheduleGroupForFullUpdate();
}
- parentPrim.HasGroupChanged = true;
- parentPrim.ScheduleGroupForFullUpdate();
}
public LSL_String llGetLinkKey(int linknum)
@@ -4200,7 +4222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
partItemID = item.ItemID;
int linkNumber = m_host.LinkNum;
- if (m_host.ParentGroup.Children.Count == 1)
+ if (m_host.ParentGroup.PrimCount == 1)
linkNumber = 0;
object[] resobj = new object[]
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 4855d64..41501f2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -209,12 +209,15 @@ namespace OpenSim.Region.ScriptEngine.Shared
else
Type = 0x02; // Passive
- foreach (SceneObjectPart p in part.ParentGroup.Children.Values)
+ lock (part.ParentGroup.Children)
{
- if (p.Inventory.ContainsScripts())
+ foreach (SceneObjectPart p in part.ParentGroup.Children.Values)
{
- Type |= 0x08; // Scripted
- break;
+ if (p.Inventory.ContainsScripts())
+ {
+ Type |= 0x08; // Scripted
+ break;
+ }
}
}
--
cgit v1.1