aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs519
1 files changed, 340 insertions, 179 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 8c56870..9cb1398 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -106,6 +106,72 @@ namespace OpenSim.Region.Framework.Scenes
106 private bool m_hasGroupChanged = false; 106 private bool m_hasGroupChanged = false;
107 private long timeFirstChanged; 107 private long timeFirstChanged;
108 private long timeLastChanged; 108 private long timeLastChanged;
109 private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
110
111 public void lockPartsForRead(bool locked)
112 {
113 if (locked)
114 {
115 if (m_partsLock.RecursiveReadCount > 0)
116 {
117 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
118 m_partsLock.ExitReadLock();
119 }
120 if (m_partsLock.RecursiveWriteCount > 0)
121 {
122 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed.");
123 m_partsLock.ExitWriteLock();
124 }
125
126 while (!m_partsLock.TryEnterReadLock(60000))
127 {
128 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire READ lock of m_parts in SceneObjectGroup. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
129 if (m_partsLock.IsWriteLockHeld)
130 {
131 m_partsLock = new System.Threading.ReaderWriterLockSlim();
132 }
133 }
134 }
135 else
136 {
137 if (m_partsLock.RecursiveReadCount > 0)
138 {
139 m_partsLock.ExitReadLock();
140 }
141 }
142 }
143 public void lockPartsForWrite(bool locked)
144 {
145 if (locked)
146 {
147 if (m_partsLock.RecursiveReadCount > 0)
148 {
149 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
150 m_partsLock.ExitReadLock();
151 }
152 if (m_partsLock.RecursiveWriteCount > 0)
153 {
154 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
155 m_partsLock.ExitWriteLock();
156 }
157
158 while (!m_partsLock.TryEnterWriteLock(60000))
159 {
160 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
161 if (m_partsLock.IsWriteLockHeld)
162 {
163 m_partsLock = new System.Threading.ReaderWriterLockSlim();
164 }
165 }
166 }
167 else
168 {
169 if (m_partsLock.RecursiveWriteCount > 0)
170 {
171 m_partsLock.ExitWriteLock();
172 }
173 }
174 }
109 175
110 public bool HasGroupChanged 176 public bool HasGroupChanged
111 { 177 {
@@ -258,13 +324,16 @@ namespace OpenSim.Region.Framework.Scenes
258 set 324 set
259 { 325 {
260 m_regionHandle = value; 326 m_regionHandle = value;
261 lock (m_parts) 327 lockPartsForRead(true);
262 { 328 {
263 foreach (SceneObjectPart part in m_parts.Values) 329 foreach (SceneObjectPart part in m_parts.Values)
264 { 330 {
331
265 part.RegionHandle = m_regionHandle; 332 part.RegionHandle = m_regionHandle;
333
266 } 334 }
267 } 335 }
336 lockPartsForRead(false);
268 } 337 }
269 } 338 }
270 339
@@ -290,13 +359,16 @@ namespace OpenSim.Region.Framework.Scenes
290 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 359 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
291 } 360 }
292 361
293 lock (m_parts) 362 lockPartsForRead(true);
294 { 363 {
295 foreach (SceneObjectPart part in m_parts.Values) 364 foreach (SceneObjectPart part in m_parts.Values)
296 { 365 {
366
297 part.GroupPosition = val; 367 part.GroupPosition = val;
368
298 } 369 }
299 } 370 }
371 lockPartsForRead(false);
300 372
301 //if (m_rootPart.PhysActor != null) 373 //if (m_rootPart.PhysActor != null)
302 //{ 374 //{
@@ -458,13 +530,16 @@ namespace OpenSim.Region.Framework.Scenes
458 530
459 public void SetFromItemID(UUID AssetId) 531 public void SetFromItemID(UUID AssetId)
460 { 532 {
461 lock (m_parts) 533 lockPartsForRead(true);
462 { 534 {
463 foreach (SceneObjectPart part in m_parts.Values) 535 foreach (SceneObjectPart part in m_parts.Values)
464 { 536 {
537
465 part.FromItemID = AssetId; 538 part.FromItemID = AssetId;
539
466 } 540 }
467 } 541 }
542 lockPartsForRead(false);
468 } 543 }
469 544
470 public UUID GetFromItemID() 545 public UUID GetFromItemID()
@@ -531,10 +606,11 @@ namespace OpenSim.Region.Framework.Scenes
531 Vector3 maxScale = Vector3.Zero; 606 Vector3 maxScale = Vector3.Zero;
532 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 607 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
533 608
534 lock (m_parts) 609 lockPartsForRead(true);
535 { 610 {
536 foreach (SceneObjectPart part in m_parts.Values) 611 foreach (SceneObjectPart part in m_parts.Values)
537 { 612 {
613
538 Vector3 partscale = part.Scale; 614 Vector3 partscale = part.Scale;
539 Vector3 partoffset = part.OffsetPosition; 615 Vector3 partoffset = part.OffsetPosition;
540 616
@@ -545,8 +621,11 @@ namespace OpenSim.Region.Framework.Scenes
545 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 621 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
546 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 622 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
547 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 623 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
624
548 } 625 }
549 } 626 }
627 lockPartsForRead(false);
628
550 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 629 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
551 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 630 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
552 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 631 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -562,10 +641,11 @@ namespace OpenSim.Region.Framework.Scenes
562 641
563 EntityIntersection result = new EntityIntersection(); 642 EntityIntersection result = new EntityIntersection();
564 643
565 lock (m_parts) 644 lockPartsForRead(true);
566 { 645 {
567 foreach (SceneObjectPart part in m_parts.Values) 646 foreach (SceneObjectPart part in m_parts.Values)
568 { 647 {
648
569 // Temporary commented to stop compiler warning 649 // Temporary commented to stop compiler warning
570 //Vector3 partPosition = 650 //Vector3 partPosition =
571 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 651 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -593,8 +673,10 @@ namespace OpenSim.Region.Framework.Scenes
593 result.distance = inter.distance; 673 result.distance = inter.distance;
594 } 674 }
595 } 675 }
676
596 } 677 }
597 } 678 }
679 lockPartsForRead(false);
598 return result; 680 return result;
599 } 681 }
600 682
@@ -607,10 +689,11 @@ namespace OpenSim.Region.Framework.Scenes
607 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 689 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
608 { 690 {
609 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 691 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
610 lock (m_parts) 692 lockPartsForRead(true);
611 { 693 {
612 foreach (SceneObjectPart part in m_parts.Values) 694 foreach (SceneObjectPart part in m_parts.Values)
613 { 695 {
696
614 Vector3 worldPos = part.GetWorldPosition(); 697 Vector3 worldPos = part.GetWorldPosition();
615 Vector3 offset = worldPos - AbsolutePosition; 698 Vector3 offset = worldPos - AbsolutePosition;
616 Quaternion worldRot; 699 Quaternion worldRot;
@@ -669,6 +752,8 @@ namespace OpenSim.Region.Framework.Scenes
669 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 752 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
670 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 753 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
671 754
755
756
672 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 757 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
673 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 758 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
674 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 759 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -840,6 +925,7 @@ namespace OpenSim.Region.Framework.Scenes
840 minZ = backBottomLeft.Z; 925 minZ = backBottomLeft.Z;
841 } 926 }
842 } 927 }
928 lockPartsForRead(false);
843 929
844 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 930 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
845 931
@@ -868,17 +954,20 @@ namespace OpenSim.Region.Framework.Scenes
868 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 954 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
869 955
870 // Capture script state while holding the lock 956 // Capture script state while holding the lock
871 lock (m_parts) 957 lockPartsForRead(true);
872 { 958 {
873 foreach (SceneObjectPart part in m_parts.Values) 959 foreach (SceneObjectPart part in m_parts.Values)
874 { 960 {
961
875 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 962 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
876 foreach (UUID itemid in pstates.Keys) 963 foreach (UUID itemid in pstates.Keys)
877 { 964 {
878 states.Add(itemid, pstates[itemid]); 965 states.Add(itemid, pstates[itemid]);
879 } 966 }
967
880 } 968 }
881 } 969 }
970 lockPartsForRead(false);
882 971
883 if (states.Count > 0) 972 if (states.Count > 0)
884 { 973 {
@@ -1040,13 +1129,16 @@ namespace OpenSim.Region.Framework.Scenes
1040 1129
1041 public override void UpdateMovement() 1130 public override void UpdateMovement()
1042 { 1131 {
1043 lock (m_parts) 1132 lockPartsForRead(true);
1044 { 1133 {
1045 foreach (SceneObjectPart part in m_parts.Values) 1134 foreach (SceneObjectPart part in m_parts.Values)
1046 { 1135 {
1136
1047 part.UpdateMovement(); 1137 part.UpdateMovement();
1138
1048 } 1139 }
1049 } 1140 }
1141 lockPartsForRead(false);
1050 } 1142 }
1051 1143
1052 public ushort GetTimeDilation() 1144 public ushort GetTimeDilation()
@@ -1090,7 +1182,7 @@ namespace OpenSim.Region.Framework.Scenes
1090 /// <param name="part"></param> 1182 /// <param name="part"></param>
1091 public void AddPart(SceneObjectPart part) 1183 public void AddPart(SceneObjectPart part)
1092 { 1184 {
1093 lock (m_parts) 1185 lockPartsForWrite(true);
1094 { 1186 {
1095 part.SetParent(this); 1187 part.SetParent(this);
1096 m_parts.Add(part.UUID, part); 1188 m_parts.Add(part.UUID, part);
@@ -1100,6 +1192,7 @@ namespace OpenSim.Region.Framework.Scenes
1100 if (part.LinkNum == 2 && RootPart != null) 1192 if (part.LinkNum == 2 && RootPart != null)
1101 RootPart.LinkNum = 1; 1193 RootPart.LinkNum = 1;
1102 } 1194 }
1195 lockPartsForWrite(false);
1103 } 1196 }
1104 1197
1105 /// <summary> 1198 /// <summary>
@@ -1107,28 +1200,33 @@ namespace OpenSim.Region.Framework.Scenes
1107 /// </summary> 1200 /// </summary>
1108 private void UpdateParentIDs() 1201 private void UpdateParentIDs()
1109 { 1202 {
1110 lock (m_parts) 1203 lockPartsForRead(true);
1111 { 1204 {
1112 foreach (SceneObjectPart part in m_parts.Values) 1205 foreach (SceneObjectPart part in m_parts.Values)
1113 { 1206 {
1207
1114 if (part.UUID != m_rootPart.UUID) 1208 if (part.UUID != m_rootPart.UUID)
1115 { 1209 {
1116 part.ParentID = m_rootPart.LocalId; 1210 part.ParentID = m_rootPart.LocalId;
1117 } 1211 }
1212
1118 } 1213 }
1119 } 1214 }
1215 lockPartsForRead(false);
1120 } 1216 }
1121 1217
1122 public void RegenerateFullIDs() 1218 public void RegenerateFullIDs()
1123 { 1219 {
1124 lock (m_parts) 1220 lockPartsForRead(true);
1125 { 1221 {
1126 foreach (SceneObjectPart part in m_parts.Values) 1222 foreach (SceneObjectPart part in m_parts.Values)
1127 { 1223 {
1224
1128 part.UUID = UUID.Random(); 1225 part.UUID = UUID.Random();
1129 1226
1130 } 1227 }
1131 } 1228 }
1229 lockPartsForRead(false);
1132 } 1230 }
1133 1231
1134 // helper provided for parts. 1232 // helper provided for parts.
@@ -1209,29 +1307,33 @@ namespace OpenSim.Region.Framework.Scenes
1209 1307
1210 DetachFromBackup(); 1308 DetachFromBackup();
1211 1309
1212 lock (m_parts) 1310 lockPartsForRead(true);
1311 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1312 lockPartsForRead(false);
1313
1314 foreach (SceneObjectPart part in values)
1213 { 1315 {
1214 foreach (SceneObjectPart part in m_parts.Values)
1215 {
1216// part.Inventory.RemoveScriptInstances(); 1316// part.Inventory.RemoveScriptInstances();
1217 1317
1218 ScenePresence[] avatars = Scene.GetScenePresences(); 1318 ScenePresence[] avatars = Scene.GetScenePresences();
1219 for (int i = 0; i < avatars.Length; i++) 1319 for (int i = 0; i < avatars.Length; i++)
1320 {
1321 if (avatars[i].ParentID == LocalId)
1220 { 1322 {
1221 if (avatars[i].ParentID == LocalId) 1323 avatars[i].StandUp();
1222 { 1324 }
1223 avatars[i].StandUp();
1224 }
1225 1325
1226 if (!silent) 1326 if (!silent)
1227 { 1327 {
1228 part.UpdateFlag = 0; 1328 part.UpdateFlag = 0;
1229 if (part == m_rootPart) 1329 if (part == m_rootPart)
1230 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1330 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1231 }
1232 } 1331 }
1233 } 1332 }
1333
1234 } 1334 }
1335
1336
1235 } 1337 }
1236 1338
1237 public void AddScriptLPS(int count) 1339 public void AddScriptLPS(int count)
@@ -1256,17 +1358,20 @@ namespace OpenSim.Region.Framework.Scenes
1256 1358
1257 scriptEvents aggregateScriptEvents=0; 1359 scriptEvents aggregateScriptEvents=0;
1258 1360
1259 lock (m_parts) 1361 lockPartsForRead(true);
1260 { 1362 {
1261 foreach (SceneObjectPart part in m_parts.Values) 1363 foreach (SceneObjectPart part in m_parts.Values)
1262 { 1364 {
1365
1263 if (part == null) 1366 if (part == null)
1264 continue; 1367 continue;
1265 if (part != RootPart) 1368 if (part != RootPart)
1266 part.ObjectFlags = objectflagupdate; 1369 part.ObjectFlags = objectflagupdate;
1267 aggregateScriptEvents |= part.AggregateScriptEvents; 1370 aggregateScriptEvents |= part.AggregateScriptEvents;
1371
1268 } 1372 }
1269 } 1373 }
1374 lockPartsForRead(false);
1270 1375
1271 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1376 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1272 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1377 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1308,42 +1413,52 @@ namespace OpenSim.Region.Framework.Scenes
1308 /// <param name="m_physicalPrim"></param> 1413 /// <param name="m_physicalPrim"></param>
1309 public void ApplyPhysics(bool m_physicalPrim) 1414 public void ApplyPhysics(bool m_physicalPrim)
1310 { 1415 {
1311 lock (m_parts) 1416 lockPartsForRead(true);
1417
1418 if (m_parts.Count > 1)
1312 { 1419 {
1313 if (m_parts.Count > 1) 1420 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1421 lockPartsForRead(false);
1422 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1423 foreach (SceneObjectPart part in values)
1314 { 1424 {
1315 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1425
1316 foreach (SceneObjectPart part in m_parts.Values) 1426 if (part.LocalId != m_rootPart.LocalId)
1317 { 1427 {
1318 if (part.LocalId != m_rootPart.LocalId) 1428 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1319 {
1320 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1321 }
1322 } 1429 }
1323 1430
1324 // Hack to get the physics scene geometries in the right spot
1325 ResetChildPrimPhysicsPositions();
1326 }
1327 else
1328 {
1329 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1330 } 1431 }
1432 // Hack to get the physics scene geometries in the right spot
1433 ResetChildPrimPhysicsPositions();
1434 }
1435 else
1436 {
1437 lockPartsForRead(false);
1438 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1331 } 1439 }
1332 } 1440 }
1333 1441
1334 public void SetOwnerId(UUID userId) 1442 public void SetOwnerId(UUID userId)
1335 { 1443 {
1336 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1444 ForEachPart(delegate(SceneObjectPart part)
1445 {
1446
1447 part.OwnerID = userId;
1448
1449 });
1337 } 1450 }
1338 1451
1339 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1452 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1340 { 1453 {
1341 lock (m_parts) 1454 lockPartsForRead(true);
1455 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1456 lockPartsForRead(false);
1457 foreach (SceneObjectPart part in values)
1342 { 1458 {
1343 foreach (SceneObjectPart part in m_parts.Values) 1459
1344 { 1460 whatToDo(part);
1345 whatToDo(part); 1461
1346 }
1347 } 1462 }
1348 } 1463 }
1349 1464
@@ -1442,14 +1557,17 @@ namespace OpenSim.Region.Framework.Scenes
1442 { 1557 {
1443 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1558 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1444 1559
1445 lock (m_parts) 1560 lockPartsForRead(true);
1446 { 1561 {
1447 foreach (SceneObjectPart part in m_parts.Values) 1562 foreach (SceneObjectPart part in m_parts.Values)
1448 { 1563 {
1564
1449 if (part != RootPart) 1565 if (part != RootPart)
1450 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1566 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1567
1451 } 1568 }
1452 } 1569 }
1570 lockPartsForRead(false);
1453 } 1571 }
1454 1572
1455 /// <summary> 1573 /// <summary>
@@ -1544,10 +1662,11 @@ namespace OpenSim.Region.Framework.Scenes
1544 1662
1545 List<SceneObjectPart> partList; 1663 List<SceneObjectPart> partList;
1546 1664
1547 lock (m_parts) 1665 lockPartsForRead(true);
1548 { 1666
1549 partList = new List<SceneObjectPart>(m_parts.Values); 1667 partList = new List<SceneObjectPart>(m_parts.Values);
1550 } 1668
1669 lockPartsForRead(false);
1551 1670
1552 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1671 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1553 { 1672 {
@@ -1796,6 +1915,7 @@ namespace OpenSim.Region.Framework.Scenes
1796 } 1915 }
1797 } 1916 }
1798 } 1917 }
1918
1799 public void stopLookAt() 1919 public void stopLookAt()
1800 { 1920 {
1801 SceneObjectPart rootpart = m_rootPart; 1921 SceneObjectPart rootpart = m_rootPart;
@@ -1870,10 +1990,11 @@ namespace OpenSim.Region.Framework.Scenes
1870 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1990 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1871 newPart.SetParent(this); 1991 newPart.SetParent(this);
1872 1992
1873 lock (m_parts) 1993 lockPartsForWrite(true);
1874 { 1994 {
1875 m_parts.Add(newPart.UUID, newPart); 1995 m_parts.Add(newPart.UUID, newPart);
1876 } 1996 }
1997 lockPartsForWrite(false);
1877 1998
1878 SetPartAsNonRoot(newPart); 1999 SetPartAsNonRoot(newPart);
1879 2000
@@ -1936,7 +2057,7 @@ namespace OpenSim.Region.Framework.Scenes
1936 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2057 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1937 // return; 2058 // return;
1938 2059
1939 lock (m_parts) 2060 lockPartsForRead(true);
1940 { 2061 {
1941 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2062 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1942 2063
@@ -1954,34 +2075,43 @@ namespace OpenSim.Region.Framework.Scenes
1954 2075
1955 foreach (SceneObjectPart part in m_parts.Values) 2076 foreach (SceneObjectPart part in m_parts.Values)
1956 { 2077 {
2078
1957 part.SendScheduledUpdates(); 2079 part.SendScheduledUpdates();
2080
1958 } 2081 }
1959 } 2082 }
2083 lockPartsForRead(false);
1960 } 2084 }
1961 2085
1962 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2086 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1963 { 2087 {
1964 RootPart.AddFullUpdateToAvatar(presence); 2088 RootPart.AddFullUpdateToAvatar(presence);
1965 2089
1966 lock (m_parts) 2090 lockPartsForRead(true);
1967 { 2091 {
1968 foreach (SceneObjectPart part in m_parts.Values) 2092 foreach (SceneObjectPart part in m_parts.Values)
1969 { 2093 {
2094
1970 if (part != RootPart) 2095 if (part != RootPart)
1971 part.AddFullUpdateToAvatar(presence); 2096 part.AddFullUpdateToAvatar(presence);
2097
1972 } 2098 }
1973 } 2099 }
2100 lockPartsForRead(false);
1974 } 2101 }
1975 2102
1976 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2103 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1977 { 2104 {
1978 lock (m_parts) 2105 lockPartsForRead(true);
1979 { 2106 {
1980 foreach (SceneObjectPart part in m_parts.Values) 2107 foreach (SceneObjectPart part in m_parts.Values)
1981 { 2108 {
2109
1982 part.AddTerseUpdateToAvatar(presence); 2110 part.AddTerseUpdateToAvatar(presence);
2111
1983 } 2112 }
1984 } 2113 }
2114 lockPartsForRead(false);
1985 } 2115 }
1986 2116
1987 /// <summary> 2117 /// <summary>
@@ -1992,14 +2122,17 @@ namespace OpenSim.Region.Framework.Scenes
1992 checkAtTargets(); 2122 checkAtTargets();
1993 RootPart.ScheduleFullUpdate(); 2123 RootPart.ScheduleFullUpdate();
1994 2124
1995 lock (m_parts) 2125 lockPartsForRead(true);
1996 { 2126 {
1997 foreach (SceneObjectPart part in m_parts.Values) 2127 foreach (SceneObjectPart part in m_parts.Values)
1998 { 2128 {
2129
1999 if (part != RootPart) 2130 if (part != RootPart)
2000 part.ScheduleFullUpdate(); 2131 part.ScheduleFullUpdate();
2132
2001 } 2133 }
2002 } 2134 }
2135 lockPartsForRead(false);
2003 } 2136 }
2004 2137
2005 /// <summary> 2138 /// <summary>
@@ -2007,13 +2140,16 @@ namespace OpenSim.Region.Framework.Scenes
2007 /// </summary> 2140 /// </summary>
2008 public void ScheduleGroupForTerseUpdate() 2141 public void ScheduleGroupForTerseUpdate()
2009 { 2142 {
2010 lock (m_parts) 2143 lockPartsForRead(true);
2011 { 2144 {
2012 foreach (SceneObjectPart part in m_parts.Values) 2145 foreach (SceneObjectPart part in m_parts.Values)
2013 { 2146 {
2147
2014 part.ScheduleTerseUpdate(); 2148 part.ScheduleTerseUpdate();
2149
2015 } 2150 }
2016 } 2151 }
2152 lockPartsForRead(false);
2017 } 2153 }
2018 2154
2019 /// <summary> 2155 /// <summary>
@@ -2026,14 +2162,17 @@ namespace OpenSim.Region.Framework.Scenes
2026 2162
2027 RootPart.SendFullUpdateToAllClients(); 2163 RootPart.SendFullUpdateToAllClients();
2028 2164
2029 lock (m_parts) 2165 lockPartsForRead(true);
2030 { 2166 {
2031 foreach (SceneObjectPart part in m_parts.Values) 2167 foreach (SceneObjectPart part in m_parts.Values)
2032 { 2168 {
2169
2033 if (part != RootPart) 2170 if (part != RootPart)
2034 part.SendFullUpdateToAllClients(); 2171 part.SendFullUpdateToAllClients();
2172
2035 } 2173 }
2036 } 2174 }
2175 lockPartsForRead(false);
2037 } 2176 }
2038 2177
2039 /// <summary> 2178 /// <summary>
@@ -2064,14 +2203,15 @@ namespace OpenSim.Region.Framework.Scenes
2064 { 2203 {
2065 if (IsDeleted) 2204 if (IsDeleted)
2066 return; 2205 return;
2067 2206
2068 lock (m_parts) 2207 lockPartsForRead(true);
2069 { 2208 {
2070 foreach (SceneObjectPart part in m_parts.Values) 2209 foreach (SceneObjectPart part in m_parts.Values)
2071 { 2210 {
2072 part.SendTerseUpdateToAllClients(); 2211 part.SendTerseUpdateToAllClients();
2073 } 2212 }
2074 } 2213 }
2214 lockPartsForRead(false);
2075 } 2215 }
2076 2216
2077 #endregion 2217 #endregion
@@ -2085,16 +2225,18 @@ namespace OpenSim.Region.Framework.Scenes
2085 /// <returns>null if no child part with that linknum or child part</returns> 2225 /// <returns>null if no child part with that linknum or child part</returns>
2086 public SceneObjectPart GetLinkNumPart(int linknum) 2226 public SceneObjectPart GetLinkNumPart(int linknum)
2087 { 2227 {
2088 lock (m_parts) 2228 lockPartsForRead(true);
2089 { 2229 {
2090 foreach (SceneObjectPart part in m_parts.Values) 2230 foreach (SceneObjectPart part in m_parts.Values)
2091 { 2231 {
2092 if (part.LinkNum == linknum) 2232 if (part.LinkNum == linknum)
2093 { 2233 {
2234 lockPartsForRead(false);
2094 return part; 2235 return part;
2095 } 2236 }
2096 } 2237 }
2097 } 2238 }
2239 lockPartsForRead(false);
2098 2240
2099 return null; 2241 return null;
2100 } 2242 }
@@ -2122,17 +2264,19 @@ namespace OpenSim.Region.Framework.Scenes
2122 public SceneObjectPart GetChildPart(uint localID) 2264 public SceneObjectPart GetChildPart(uint localID)
2123 { 2265 {
2124 //m_log.DebugFormat("Entered looking for {0}", localID); 2266 //m_log.DebugFormat("Entered looking for {0}", localID);
2125 lock (m_parts) 2267 lockPartsForRead(true);
2126 { 2268 {
2127 foreach (SceneObjectPart part in m_parts.Values) 2269 foreach (SceneObjectPart part in m_parts.Values)
2128 { 2270 {
2129 //m_log.DebugFormat("Found {0}", part.LocalId); 2271 //m_log.DebugFormat("Found {0}", part.LocalId);
2130 if (part.LocalId == localID) 2272 if (part.LocalId == localID)
2131 { 2273 {
2274 lockPartsForRead(false);
2132 return part; 2275 return part;
2133 } 2276 }
2134 } 2277 }
2135 } 2278 }
2279 lockPartsForRead(false);
2136 2280
2137 return null; 2281 return null;
2138 } 2282 }
@@ -2162,17 +2306,19 @@ namespace OpenSim.Region.Framework.Scenes
2162 public bool HasChildPrim(uint localID) 2306 public bool HasChildPrim(uint localID)
2163 { 2307 {
2164 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2308 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2165 lock (m_parts) 2309 lockPartsForRead(true);
2166 { 2310 {
2167 foreach (SceneObjectPart part in m_parts.Values) 2311 foreach (SceneObjectPart part in m_parts.Values)
2168 { 2312 {
2169 //m_log.DebugFormat("Found {0}", part.LocalId); 2313 //m_log.DebugFormat("Found {0}", part.LocalId);
2170 if (part.LocalId == localID) 2314 if (part.LocalId == localID)
2171 { 2315 {
2316 lockPartsForRead(false);
2172 return true; 2317 return true;
2173 } 2318 }
2174 } 2319 }
2175 } 2320 }
2321 lockPartsForRead(false);
2176 2322
2177 return false; 2323 return false;
2178 } 2324 }
@@ -2222,53 +2368,57 @@ namespace OpenSim.Region.Framework.Scenes
2222 if (m_rootPart.LinkNum == 0) 2368 if (m_rootPart.LinkNum == 0)
2223 m_rootPart.LinkNum = 1; 2369 m_rootPart.LinkNum = 1;
2224 2370
2225 lock (m_parts) 2371 lockPartsForWrite(true);
2226 { 2372
2227 m_parts.Add(linkPart.UUID, linkPart); 2373 m_parts.Add(linkPart.UUID, linkPart);
2228 2374
2229 // Insert in terms of link numbers, the new links 2375 lockPartsForWrite(false);
2230 // before the current ones (with the exception of 2376
2231 // the root prim. Shuffle the old ones up 2377 // Insert in terms of link numbers, the new links
2232 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2378 // before the current ones (with the exception of
2379 // the root prim. Shuffle the old ones up
2380 lockPartsForRead(true);
2381 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2382 {
2383 if (kvp.Value.LinkNum != 1)
2233 { 2384 {
2234 if (kvp.Value.LinkNum != 1) 2385 // Don't update root prim link number
2235 { 2386 kvp.Value.LinkNum += objectGroup.PrimCount;
2236 // Don't update root prim link number
2237 kvp.Value.LinkNum += objectGroup.PrimCount;
2238 }
2239 } 2387 }
2388 }
2389 lockPartsForRead(false);
2240 2390
2241 linkPart.LinkNum = 2; 2391 linkPart.LinkNum = 2;
2242 2392
2243 linkPart.SetParent(this); 2393 linkPart.SetParent(this);
2244 linkPart.AddFlag(PrimFlags.CreateSelected); 2394 linkPart.AddFlag(PrimFlags.CreateSelected);
2245 2395
2246 //if (linkPart.PhysActor != null) 2396 //if (linkPart.PhysActor != null)
2247 //{ 2397 //{
2248 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2398 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2249 2399
2250 //linkPart.PhysActor = null; 2400 //linkPart.PhysActor = null;
2251 //} 2401 //}
2252 2402
2253 //TODO: rest of parts 2403 //TODO: rest of parts
2254 int linkNum = 3; 2404 int linkNum = 3;
2255 foreach (SceneObjectPart part in objectGroup.Children.Values) 2405 foreach (SceneObjectPart part in objectGroup.Children.Values)
2406 {
2407 if (part.UUID != objectGroup.m_rootPart.UUID)
2256 { 2408 {
2257 if (part.UUID != objectGroup.m_rootPart.UUID) 2409 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2258 {
2259 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2260 }
2261 part.ClearUndoState();
2262 } 2410 }
2411 part.ClearUndoState();
2263 } 2412 }
2264 2413
2265 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2414 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2266 objectGroup.m_isDeleted = true; 2415 objectGroup.m_isDeleted = true;
2416
2417 objectGroup.lockPartsForWrite(true);
2267 2418
2268 lock (objectGroup.m_parts) 2419 objectGroup.m_parts.Clear();
2269 { 2420
2270 objectGroup.m_parts.Clear(); 2421 objectGroup.lockPartsForWrite(false);
2271 }
2272 2422
2273 // Can't do this yet since backup still makes use of the root part without any synchronization 2423 // Can't do this yet since backup still makes use of the root part without any synchronization
2274// objectGroup.m_rootPart = null; 2424// objectGroup.m_rootPart = null;
@@ -2327,11 +2477,12 @@ namespace OpenSim.Region.Framework.Scenes
2327 Quaternion worldRot = linkPart.GetWorldRotation(); 2477 Quaternion worldRot = linkPart.GetWorldRotation();
2328 2478
2329 // Remove the part from this object 2479 // Remove the part from this object
2330 lock (m_parts) 2480 lockPartsForWrite(true);
2331 { 2481 {
2332 m_parts.Remove(linkPart.UUID); 2482 m_parts.Remove(linkPart.UUID);
2333 } 2483 }
2334 2484 lockPartsForWrite(false);
2485 lockPartsForRead(true);
2335 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2486 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2336 RootPart.LinkNum = 0; 2487 RootPart.LinkNum = 0;
2337 else 2488 else
@@ -2342,6 +2493,7 @@ namespace OpenSim.Region.Framework.Scenes
2342 p.LinkNum--; 2493 p.LinkNum--;
2343 } 2494 }
2344 } 2495 }
2496 lockPartsForRead(false);
2345 2497
2346 linkPart.ParentID = 0; 2498 linkPart.ParentID = 0;
2347 linkPart.LinkNum = 0; 2499 linkPart.LinkNum = 0;
@@ -2659,9 +2811,12 @@ namespace OpenSim.Region.Framework.Scenes
2659 2811
2660 if (selectionPart != null) 2812 if (selectionPart != null)
2661 { 2813 {
2662 lock (m_parts) 2814 lockPartsForRead(true);
2815 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2816 lockPartsForRead(false);
2817 foreach (SceneObjectPart part in parts)
2663 { 2818 {
2664 foreach (SceneObjectPart part in m_parts.Values) 2819 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2665 { 2820 {
2666 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2821 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2667 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2822 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2671,12 +2826,13 @@ namespace OpenSim.Region.Framework.Scenes
2671 break; 2826 break;
2672 } 2827 }
2673 } 2828 }
2829 }
2674 2830
2675 foreach (SceneObjectPart part in m_parts.Values) 2831 foreach (SceneObjectPart part in parts)
2676 { 2832 {
2677 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2833 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2678 }
2679 } 2834 }
2835
2680 } 2836 }
2681 } 2837 }
2682 2838
@@ -2762,11 +2918,9 @@ namespace OpenSim.Region.Framework.Scenes
2762 scale.Y = m_scene.m_maxNonphys; 2918 scale.Y = m_scene.m_maxNonphys;
2763 if (scale.Z > m_scene.m_maxNonphys) 2919 if (scale.Z > m_scene.m_maxNonphys)
2764 scale.Z = m_scene.m_maxNonphys; 2920 scale.Z = m_scene.m_maxNonphys;
2765
2766 SceneObjectPart part = GetChildPart(localID); 2921 SceneObjectPart part = GetChildPart(localID);
2767 if (part != null) 2922 if (part != null)
2768 { 2923 {
2769 part.Resize(scale);
2770 if (part.PhysActor != null) 2924 if (part.PhysActor != null)
2771 { 2925 {
2772 if (part.PhysActor.IsPhysical) 2926 if (part.PhysActor.IsPhysical)
@@ -2781,7 +2935,7 @@ namespace OpenSim.Region.Framework.Scenes
2781 part.PhysActor.Size = scale; 2935 part.PhysActor.Size = scale;
2782 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2936 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2783 } 2937 }
2784 //if (part.UUID != m_rootPart.UUID) 2938 part.Resize(scale);
2785 2939
2786 HasGroupChanged = true; 2940 HasGroupChanged = true;
2787 ScheduleGroupForFullUpdate(); 2941 ScheduleGroupForFullUpdate();
@@ -2822,77 +2976,76 @@ namespace OpenSim.Region.Framework.Scenes
2822 float y = (scale.Y / part.Scale.Y); 2976 float y = (scale.Y / part.Scale.Y);
2823 float z = (scale.Z / part.Scale.Z); 2977 float z = (scale.Z / part.Scale.Z);
2824 2978
2825 lock (m_parts) 2979 lockPartsForRead(true);
2980 if (x > 1.0f || y > 1.0f || z > 1.0f)
2826 { 2981 {
2827 if (x > 1.0f || y > 1.0f || z > 1.0f) 2982 foreach (SceneObjectPart obPart in m_parts.Values)
2828 { 2983 {
2829 foreach (SceneObjectPart obPart in m_parts.Values) 2984 if (obPart.UUID != m_rootPart.UUID)
2830 { 2985 {
2831 if (obPart.UUID != m_rootPart.UUID) 2986 Vector3 oldSize = new Vector3(obPart.Scale);
2832 {
2833 Vector3 oldSize = new Vector3(obPart.Scale);
2834 2987
2835 float f = 1.0f; 2988 float f = 1.0f;
2836 float a = 1.0f; 2989 float a = 1.0f;
2837 2990
2838 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2991 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2992 {
2993 if (oldSize.X*x > m_scene.m_maxPhys)
2839 { 2994 {
2840 if (oldSize.X*x > m_scene.m_maxPhys) 2995 f = m_scene.m_maxPhys / oldSize.X;
2841 { 2996 a = f / x;
2842 f = m_scene.m_maxPhys / oldSize.X; 2997 x *= a;
2843 a = f / x; 2998 y *= a;
2844 x *= a; 2999 z *= a;
2845 y *= a;
2846 z *= a;
2847 }
2848 if (oldSize.Y*y > m_scene.m_maxPhys)
2849 {
2850 f = m_scene.m_maxPhys / oldSize.Y;
2851 a = f / y;
2852 x *= a;
2853 y *= a;
2854 z *= a;
2855 }
2856 if (oldSize.Z*z > m_scene.m_maxPhys)
2857 {
2858 f = m_scene.m_maxPhys / oldSize.Z;
2859 a = f / z;
2860 x *= a;
2861 y *= a;
2862 z *= a;
2863 }
2864 } 3000 }
2865 else 3001 if (oldSize.Y*y > m_scene.m_maxPhys)
3002 {
3003 f = m_scene.m_maxPhys / oldSize.Y;
3004 a = f / y;
3005 x *= a;
3006 y *= a;
3007 z *= a;
3008 }
3009 if (oldSize.Z*z > m_scene.m_maxPhys)
3010 {
3011 f = m_scene.m_maxPhys / oldSize.Z;
3012 a = f / z;
3013 x *= a;
3014 y *= a;
3015 z *= a;
3016 }
3017 }
3018 else
3019 {
3020 if (oldSize.X*x > m_scene.m_maxNonphys)
3021 {
3022 f = m_scene.m_maxNonphys / oldSize.X;
3023 a = f / x;
3024 x *= a;
3025 y *= a;
3026 z *= a;
3027 }
3028 if (oldSize.Y*y > m_scene.m_maxNonphys)
3029 {
3030 f = m_scene.m_maxNonphys / oldSize.Y;
3031 a = f / y;
3032 x *= a;
3033 y *= a;
3034 z *= a;
3035 }
3036 if (oldSize.Z*z > m_scene.m_maxNonphys)
2866 { 3037 {
2867 if (oldSize.X*x > m_scene.m_maxNonphys) 3038 f = m_scene.m_maxNonphys / oldSize.Z;
2868 { 3039 a = f / z;
2869 f = m_scene.m_maxNonphys / oldSize.X; 3040 x *= a;
2870 a = f / x; 3041 y *= a;
2871 x *= a; 3042 z *= a;
2872 y *= a;
2873 z *= a;
2874 }
2875 if (oldSize.Y*y > m_scene.m_maxNonphys)
2876 {
2877 f = m_scene.m_maxNonphys / oldSize.Y;
2878 a = f / y;
2879 x *= a;
2880 y *= a;
2881 z *= a;
2882 }
2883 if (oldSize.Z*z > m_scene.m_maxNonphys)
2884 {
2885 f = m_scene.m_maxNonphys / oldSize.Z;
2886 a = f / z;
2887 x *= a;
2888 y *= a;
2889 z *= a;
2890 }
2891 } 3043 }
2892 } 3044 }
2893 } 3045 }
2894 } 3046 }
2895 } 3047 }
3048 lockPartsForRead(false);
2896 3049
2897 Vector3 prevScale = part.Scale; 3050 Vector3 prevScale = part.Scale;
2898 prevScale.X *= x; 3051 prevScale.X *= x;
@@ -2900,7 +3053,7 @@ namespace OpenSim.Region.Framework.Scenes
2900 prevScale.Z *= z; 3053 prevScale.Z *= z;
2901 part.Resize(prevScale); 3054 part.Resize(prevScale);
2902 3055
2903 lock (m_parts) 3056 lockPartsForRead(true);
2904 { 3057 {
2905 foreach (SceneObjectPart obPart in m_parts.Values) 3058 foreach (SceneObjectPart obPart in m_parts.Values)
2906 { 3059 {
@@ -2919,6 +3072,7 @@ namespace OpenSim.Region.Framework.Scenes
2919 } 3072 }
2920 } 3073 }
2921 } 3074 }
3075 lockPartsForRead(false);
2922 3076
2923 if (part.PhysActor != null) 3077 if (part.PhysActor != null)
2924 { 3078 {
@@ -2999,7 +3153,7 @@ namespace OpenSim.Region.Framework.Scenes
2999 axDiff *= Quaternion.Inverse(partRotation); 3153 axDiff *= Quaternion.Inverse(partRotation);
3000 diff = axDiff; 3154 diff = axDiff;
3001 3155
3002 lock (m_parts) 3156 lockPartsForRead(true);
3003 { 3157 {
3004 foreach (SceneObjectPart obPart in m_parts.Values) 3158 foreach (SceneObjectPart obPart in m_parts.Values)
3005 { 3159 {
@@ -3009,6 +3163,7 @@ namespace OpenSim.Region.Framework.Scenes
3009 } 3163 }
3010 } 3164 }
3011 } 3165 }
3166 lockPartsForRead(false);
3012 3167
3013 AbsolutePosition = newPos; 3168 AbsolutePosition = newPos;
3014 3169
@@ -3126,7 +3281,7 @@ namespace OpenSim.Region.Framework.Scenes
3126 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3281 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3127 } 3282 }
3128 3283
3129 lock (m_parts) 3284 lockPartsForRead(true);
3130 { 3285 {
3131 foreach (SceneObjectPart prim in m_parts.Values) 3286 foreach (SceneObjectPart prim in m_parts.Values)
3132 { 3287 {
@@ -3144,6 +3299,7 @@ namespace OpenSim.Region.Framework.Scenes
3144 } 3299 }
3145 } 3300 }
3146 } 3301 }
3302 lockPartsForRead(false);
3147 3303
3148 m_rootPart.ScheduleTerseUpdate(); 3304 m_rootPart.ScheduleTerseUpdate();
3149 } 3305 }
@@ -3266,7 +3422,7 @@ namespace OpenSim.Region.Framework.Scenes
3266 if (atTargets.Count > 0) 3422 if (atTargets.Count > 0)
3267 { 3423 {
3268 uint[] localids = new uint[0]; 3424 uint[] localids = new uint[0];
3269 lock (m_parts) 3425 lockPartsForRead(true);
3270 { 3426 {
3271 localids = new uint[m_parts.Count]; 3427 localids = new uint[m_parts.Count];
3272 int cntr = 0; 3428 int cntr = 0;
@@ -3276,6 +3432,7 @@ namespace OpenSim.Region.Framework.Scenes
3276 cntr++; 3432 cntr++;
3277 } 3433 }
3278 } 3434 }
3435 lockPartsForRead(false);
3279 3436
3280 for (int ctr = 0; ctr < localids.Length; ctr++) 3437 for (int ctr = 0; ctr < localids.Length; ctr++)
3281 { 3438 {
@@ -3294,7 +3451,7 @@ namespace OpenSim.Region.Framework.Scenes
3294 { 3451 {
3295 //trigger not_at_target 3452 //trigger not_at_target
3296 uint[] localids = new uint[0]; 3453 uint[] localids = new uint[0];
3297 lock (m_parts) 3454 lockPartsForRead(true);
3298 { 3455 {
3299 localids = new uint[m_parts.Count]; 3456 localids = new uint[m_parts.Count];
3300 int cntr = 0; 3457 int cntr = 0;
@@ -3304,7 +3461,8 @@ namespace OpenSim.Region.Framework.Scenes
3304 cntr++; 3461 cntr++;
3305 } 3462 }
3306 } 3463 }
3307 3464 lockPartsForRead(false);
3465
3308 for (int ctr = 0; ctr < localids.Length; ctr++) 3466 for (int ctr = 0; ctr < localids.Length; ctr++)
3309 { 3467 {
3310 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3468 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3396,19 +3554,20 @@ namespace OpenSim.Region.Framework.Scenes
3396 public float GetMass() 3554 public float GetMass()
3397 { 3555 {
3398 float retmass = 0f; 3556 float retmass = 0f;
3399 lock (m_parts) 3557 lockPartsForRead(true);
3400 { 3558 {
3401 foreach (SceneObjectPart part in m_parts.Values) 3559 foreach (SceneObjectPart part in m_parts.Values)
3402 { 3560 {
3403 retmass += part.GetMass(); 3561 retmass += part.GetMass();
3404 } 3562 }
3405 } 3563 }
3564 lockPartsForRead(false);
3406 return retmass; 3565 return retmass;
3407 } 3566 }
3408 3567
3409 public void CheckSculptAndLoad() 3568 public void CheckSculptAndLoad()
3410 { 3569 {
3411 lock (m_parts) 3570 lockPartsForRead(true);
3412 { 3571 {
3413 if (!IsDeleted) 3572 if (!IsDeleted)
3414 { 3573 {
@@ -3433,6 +3592,7 @@ namespace OpenSim.Region.Framework.Scenes
3433 } 3592 }
3434 } 3593 }
3435 } 3594 }
3595 lockPartsForRead(false);
3436 } 3596 }
3437 3597
3438 protected void AssetReceived(string id, Object sender, AssetBase asset) 3598 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3453,7 +3613,7 @@ namespace OpenSim.Region.Framework.Scenes
3453 /// <param name="client"></param> 3613 /// <param name="client"></param>
3454 public void SetGroup(UUID GroupID, IClientAPI client) 3614 public void SetGroup(UUID GroupID, IClientAPI client)
3455 { 3615 {
3456 lock (m_parts) 3616 lockPartsForRead(true);
3457 { 3617 {
3458 foreach (SceneObjectPart part in m_parts.Values) 3618 foreach (SceneObjectPart part in m_parts.Values)
3459 { 3619 {
@@ -3463,7 +3623,7 @@ namespace OpenSim.Region.Framework.Scenes
3463 3623
3464 HasGroupChanged = true; 3624 HasGroupChanged = true;
3465 } 3625 }
3466 3626 lockPartsForRead(false);
3467 ScheduleGroupForFullUpdate(); 3627 ScheduleGroupForFullUpdate();
3468 } 3628 }
3469 3629
@@ -3482,11 +3642,12 @@ namespace OpenSim.Region.Framework.Scenes
3482 3642
3483 public void SetAttachmentPoint(byte point) 3643 public void SetAttachmentPoint(byte point)
3484 { 3644 {
3485 lock (m_parts) 3645 lockPartsForRead(true);
3486 { 3646 {
3487 foreach (SceneObjectPart part in m_parts.Values) 3647 foreach (SceneObjectPart part in m_parts.Values)
3488 part.SetAttachmentPoint(point); 3648 part.SetAttachmentPoint(point);
3489 } 3649 }
3650 lockPartsForRead(false);
3490 } 3651 }
3491 3652
3492 #region ISceneObject 3653 #region ISceneObject