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 34d8b49..e63e8d9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -98,6 +98,72 @@ namespace OpenSim.Region.Framework.Scenes
98 private bool m_hasGroupChanged = false; 98 private bool m_hasGroupChanged = false;
99 private long timeFirstChanged; 99 private long timeFirstChanged;
100 private long timeLastChanged; 100 private long timeLastChanged;
101 private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
102
103 public void lockPartsForRead(bool locked)
104 {
105 if (locked)
106 {
107 if (m_partsLock.RecursiveReadCount > 0)
108 {
109 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.");
110 m_partsLock.ExitReadLock();
111 }
112 if (m_partsLock.RecursiveWriteCount > 0)
113 {
114 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed.");
115 m_partsLock.ExitWriteLock();
116 }
117
118 while (!m_partsLock.TryEnterReadLock(60000))
119 {
120 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.");
121 if (m_partsLock.IsWriteLockHeld)
122 {
123 m_partsLock = new System.Threading.ReaderWriterLockSlim();
124 }
125 }
126 }
127 else
128 {
129 if (m_partsLock.RecursiveReadCount > 0)
130 {
131 m_partsLock.ExitReadLock();
132 }
133 }
134 }
135 public void lockPartsForWrite(bool locked)
136 {
137 if (locked)
138 {
139 if (m_partsLock.RecursiveReadCount > 0)
140 {
141 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.");
142 m_partsLock.ExitReadLock();
143 }
144 if (m_partsLock.RecursiveWriteCount > 0)
145 {
146 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
147 m_partsLock.ExitWriteLock();
148 }
149
150 while (!m_partsLock.TryEnterWriteLock(60000))
151 {
152 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.");
153 if (m_partsLock.IsWriteLockHeld)
154 {
155 m_partsLock = new System.Threading.ReaderWriterLockSlim();
156 }
157 }
158 }
159 else
160 {
161 if (m_partsLock.RecursiveWriteCount > 0)
162 {
163 m_partsLock.ExitWriteLock();
164 }
165 }
166 }
101 167
102 public bool HasGroupChanged 168 public bool HasGroupChanged
103 { 169 {
@@ -243,13 +309,16 @@ namespace OpenSim.Region.Framework.Scenes
243 set 309 set
244 { 310 {
245 m_regionHandle = value; 311 m_regionHandle = value;
246 lock (m_parts) 312 lockPartsForRead(true);
247 { 313 {
248 foreach (SceneObjectPart part in m_parts.Values) 314 foreach (SceneObjectPart part in m_parts.Values)
249 { 315 {
316
250 part.RegionHandle = m_regionHandle; 317 part.RegionHandle = m_regionHandle;
318
251 } 319 }
252 } 320 }
321 lockPartsForRead(false);
253 } 322 }
254 } 323 }
255 324
@@ -275,13 +344,16 @@ namespace OpenSim.Region.Framework.Scenes
275 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 344 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
276 } 345 }
277 346
278 lock (m_parts) 347 lockPartsForRead(true);
279 { 348 {
280 foreach (SceneObjectPart part in m_parts.Values) 349 foreach (SceneObjectPart part in m_parts.Values)
281 { 350 {
351
282 part.GroupPosition = val; 352 part.GroupPosition = val;
353
283 } 354 }
284 } 355 }
356 lockPartsForRead(false);
285 357
286 //if (m_rootPart.PhysActor != null) 358 //if (m_rootPart.PhysActor != null)
287 //{ 359 //{
@@ -443,13 +515,16 @@ namespace OpenSim.Region.Framework.Scenes
443 515
444 public void SetFromItemID(UUID AssetId) 516 public void SetFromItemID(UUID AssetId)
445 { 517 {
446 lock (m_parts) 518 lockPartsForRead(true);
447 { 519 {
448 foreach (SceneObjectPart part in m_parts.Values) 520 foreach (SceneObjectPart part in m_parts.Values)
449 { 521 {
522
450 part.FromItemID = AssetId; 523 part.FromItemID = AssetId;
524
451 } 525 }
452 } 526 }
527 lockPartsForRead(false);
453 } 528 }
454 529
455 public UUID GetFromItemID() 530 public UUID GetFromItemID()
@@ -516,10 +591,11 @@ namespace OpenSim.Region.Framework.Scenes
516 Vector3 maxScale = Vector3.Zero; 591 Vector3 maxScale = Vector3.Zero;
517 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 592 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
518 593
519 lock (m_parts) 594 lockPartsForRead(true);
520 { 595 {
521 foreach (SceneObjectPart part in m_parts.Values) 596 foreach (SceneObjectPart part in m_parts.Values)
522 { 597 {
598
523 Vector3 partscale = part.Scale; 599 Vector3 partscale = part.Scale;
524 Vector3 partoffset = part.OffsetPosition; 600 Vector3 partoffset = part.OffsetPosition;
525 601
@@ -530,8 +606,11 @@ namespace OpenSim.Region.Framework.Scenes
530 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 606 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
531 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 607 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
532 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 608 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
609
533 } 610 }
534 } 611 }
612 lockPartsForRead(false);
613
535 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 614 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
536 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 615 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
537 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 616 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -547,10 +626,11 @@ namespace OpenSim.Region.Framework.Scenes
547 626
548 EntityIntersection result = new EntityIntersection(); 627 EntityIntersection result = new EntityIntersection();
549 628
550 lock (m_parts) 629 lockPartsForRead(true);
551 { 630 {
552 foreach (SceneObjectPart part in m_parts.Values) 631 foreach (SceneObjectPart part in m_parts.Values)
553 { 632 {
633
554 // Temporary commented to stop compiler warning 634 // Temporary commented to stop compiler warning
555 //Vector3 partPosition = 635 //Vector3 partPosition =
556 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 636 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -578,8 +658,10 @@ namespace OpenSim.Region.Framework.Scenes
578 result.distance = inter.distance; 658 result.distance = inter.distance;
579 } 659 }
580 } 660 }
661
581 } 662 }
582 } 663 }
664 lockPartsForRead(false);
583 return result; 665 return result;
584 } 666 }
585 667
@@ -592,10 +674,11 @@ namespace OpenSim.Region.Framework.Scenes
592 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 674 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
593 { 675 {
594 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 676 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
595 lock (m_parts) 677 lockPartsForRead(true);
596 { 678 {
597 foreach (SceneObjectPart part in m_parts.Values) 679 foreach (SceneObjectPart part in m_parts.Values)
598 { 680 {
681
599 Vector3 worldPos = part.GetWorldPosition(); 682 Vector3 worldPos = part.GetWorldPosition();
600 Vector3 offset = worldPos - AbsolutePosition; 683 Vector3 offset = worldPos - AbsolutePosition;
601 Quaternion worldRot; 684 Quaternion worldRot;
@@ -654,6 +737,8 @@ namespace OpenSim.Region.Framework.Scenes
654 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 737 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
655 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 738 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
656 739
740
741
657 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 742 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
658 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 743 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
659 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 744 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -825,6 +910,7 @@ namespace OpenSim.Region.Framework.Scenes
825 minZ = backBottomLeft.Z; 910 minZ = backBottomLeft.Z;
826 } 911 }
827 } 912 }
913 lockPartsForRead(false);
828 914
829 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 915 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
830 916
@@ -853,17 +939,20 @@ namespace OpenSim.Region.Framework.Scenes
853 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 939 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
854 940
855 // Capture script state while holding the lock 941 // Capture script state while holding the lock
856 lock (m_parts) 942 lockPartsForRead(true);
857 { 943 {
858 foreach (SceneObjectPart part in m_parts.Values) 944 foreach (SceneObjectPart part in m_parts.Values)
859 { 945 {
946
860 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 947 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
861 foreach (UUID itemid in pstates.Keys) 948 foreach (UUID itemid in pstates.Keys)
862 { 949 {
863 states.Add(itemid, pstates[itemid]); 950 states.Add(itemid, pstates[itemid]);
864 } 951 }
952
865 } 953 }
866 } 954 }
955 lockPartsForRead(false);
867 956
868 if (states.Count > 0) 957 if (states.Count > 0)
869 { 958 {
@@ -1025,13 +1114,16 @@ namespace OpenSim.Region.Framework.Scenes
1025 1114
1026 public override void UpdateMovement() 1115 public override void UpdateMovement()
1027 { 1116 {
1028 lock (m_parts) 1117 lockPartsForRead(true);
1029 { 1118 {
1030 foreach (SceneObjectPart part in m_parts.Values) 1119 foreach (SceneObjectPart part in m_parts.Values)
1031 { 1120 {
1121
1032 part.UpdateMovement(); 1122 part.UpdateMovement();
1123
1033 } 1124 }
1034 } 1125 }
1126 lockPartsForRead(false);
1035 } 1127 }
1036 1128
1037 public ushort GetTimeDilation() 1129 public ushort GetTimeDilation()
@@ -1075,7 +1167,7 @@ namespace OpenSim.Region.Framework.Scenes
1075 /// <param name="part"></param> 1167 /// <param name="part"></param>
1076 public void AddPart(SceneObjectPart part) 1168 public void AddPart(SceneObjectPart part)
1077 { 1169 {
1078 lock (m_parts) 1170 lockPartsForWrite(true);
1079 { 1171 {
1080 part.SetParent(this); 1172 part.SetParent(this);
1081 m_parts.Add(part.UUID, part); 1173 m_parts.Add(part.UUID, part);
@@ -1085,6 +1177,7 @@ namespace OpenSim.Region.Framework.Scenes
1085 if (part.LinkNum == 2 && RootPart != null) 1177 if (part.LinkNum == 2 && RootPart != null)
1086 RootPart.LinkNum = 1; 1178 RootPart.LinkNum = 1;
1087 } 1179 }
1180 lockPartsForWrite(false);
1088 } 1181 }
1089 1182
1090 /// <summary> 1183 /// <summary>
@@ -1092,28 +1185,33 @@ namespace OpenSim.Region.Framework.Scenes
1092 /// </summary> 1185 /// </summary>
1093 private void UpdateParentIDs() 1186 private void UpdateParentIDs()
1094 { 1187 {
1095 lock (m_parts) 1188 lockPartsForRead(true);
1096 { 1189 {
1097 foreach (SceneObjectPart part in m_parts.Values) 1190 foreach (SceneObjectPart part in m_parts.Values)
1098 { 1191 {
1192
1099 if (part.UUID != m_rootPart.UUID) 1193 if (part.UUID != m_rootPart.UUID)
1100 { 1194 {
1101 part.ParentID = m_rootPart.LocalId; 1195 part.ParentID = m_rootPart.LocalId;
1102 } 1196 }
1197
1103 } 1198 }
1104 } 1199 }
1200 lockPartsForRead(false);
1105 } 1201 }
1106 1202
1107 public void RegenerateFullIDs() 1203 public void RegenerateFullIDs()
1108 { 1204 {
1109 lock (m_parts) 1205 lockPartsForRead(true);
1110 { 1206 {
1111 foreach (SceneObjectPart part in m_parts.Values) 1207 foreach (SceneObjectPart part in m_parts.Values)
1112 { 1208 {
1209
1113 part.UUID = UUID.Random(); 1210 part.UUID = UUID.Random();
1114 1211
1115 } 1212 }
1116 } 1213 }
1214 lockPartsForRead(false);
1117 } 1215 }
1118 1216
1119 // helper provided for parts. 1217 // helper provided for parts.
@@ -1194,29 +1292,33 @@ namespace OpenSim.Region.Framework.Scenes
1194 1292
1195 DetachFromBackup(); 1293 DetachFromBackup();
1196 1294
1197 lock (m_parts) 1295 lockPartsForRead(true);
1296 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1297 lockPartsForRead(false);
1298
1299 foreach (SceneObjectPart part in values)
1198 { 1300 {
1199 foreach (SceneObjectPart part in m_parts.Values)
1200 {
1201// part.Inventory.RemoveScriptInstances(); 1301// part.Inventory.RemoveScriptInstances();
1202 1302
1203 ScenePresence[] avatars = Scene.GetScenePresences(); 1303 ScenePresence[] avatars = Scene.GetScenePresences();
1204 for (int i = 0; i < avatars.Length; i++) 1304 for (int i = 0; i < avatars.Length; i++)
1305 {
1306 if (avatars[i].ParentID == LocalId)
1205 { 1307 {
1206 if (avatars[i].ParentID == LocalId) 1308 avatars[i].StandUp();
1207 { 1309 }
1208 avatars[i].StandUp();
1209 }
1210 1310
1211 if (!silent) 1311 if (!silent)
1212 { 1312 {
1213 part.UpdateFlag = 0; 1313 part.UpdateFlag = 0;
1214 if (part == m_rootPart) 1314 if (part == m_rootPart)
1215 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1315 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1216 }
1217 } 1316 }
1218 } 1317 }
1318
1219 } 1319 }
1320
1321
1220 } 1322 }
1221 1323
1222 public void AddScriptLPS(int count) 1324 public void AddScriptLPS(int count)
@@ -1241,17 +1343,20 @@ namespace OpenSim.Region.Framework.Scenes
1241 1343
1242 scriptEvents aggregateScriptEvents=0; 1344 scriptEvents aggregateScriptEvents=0;
1243 1345
1244 lock (m_parts) 1346 lockPartsForRead(true);
1245 { 1347 {
1246 foreach (SceneObjectPart part in m_parts.Values) 1348 foreach (SceneObjectPart part in m_parts.Values)
1247 { 1349 {
1350
1248 if (part == null) 1351 if (part == null)
1249 continue; 1352 continue;
1250 if (part != RootPart) 1353 if (part != RootPart)
1251 part.ObjectFlags = objectflagupdate; 1354 part.ObjectFlags = objectflagupdate;
1252 aggregateScriptEvents |= part.AggregateScriptEvents; 1355 aggregateScriptEvents |= part.AggregateScriptEvents;
1356
1253 } 1357 }
1254 } 1358 }
1359 lockPartsForRead(false);
1255 1360
1256 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1361 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1257 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1362 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1284,42 +1389,52 @@ namespace OpenSim.Region.Framework.Scenes
1284 /// <param name="m_physicalPrim"></param> 1389 /// <param name="m_physicalPrim"></param>
1285 public void ApplyPhysics(bool m_physicalPrim) 1390 public void ApplyPhysics(bool m_physicalPrim)
1286 { 1391 {
1287 lock (m_parts) 1392 lockPartsForRead(true);
1393
1394 if (m_parts.Count > 1)
1288 { 1395 {
1289 if (m_parts.Count > 1) 1396 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1397 lockPartsForRead(false);
1398 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1399 foreach (SceneObjectPart part in values)
1290 { 1400 {
1291 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1401
1292 foreach (SceneObjectPart part in m_parts.Values) 1402 if (part.LocalId != m_rootPart.LocalId)
1293 { 1403 {
1294 if (part.LocalId != m_rootPart.LocalId) 1404 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1295 {
1296 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1297 }
1298 } 1405 }
1299 1406
1300 // Hack to get the physics scene geometries in the right spot
1301 ResetChildPrimPhysicsPositions();
1302 }
1303 else
1304 {
1305 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1306 } 1407 }
1408 // Hack to get the physics scene geometries in the right spot
1409 ResetChildPrimPhysicsPositions();
1410 }
1411 else
1412 {
1413 lockPartsForRead(false);
1414 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1307 } 1415 }
1308 } 1416 }
1309 1417
1310 public void SetOwnerId(UUID userId) 1418 public void SetOwnerId(UUID userId)
1311 { 1419 {
1312 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1420 ForEachPart(delegate(SceneObjectPart part)
1421 {
1422
1423 part.OwnerID = userId;
1424
1425 });
1313 } 1426 }
1314 1427
1315 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1428 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1316 { 1429 {
1317 lock (m_parts) 1430 lockPartsForRead(true);
1431 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1432 lockPartsForRead(false);
1433 foreach (SceneObjectPart part in values)
1318 { 1434 {
1319 foreach (SceneObjectPart part in m_parts.Values) 1435
1320 { 1436 whatToDo(part);
1321 whatToDo(part); 1437
1322 }
1323 } 1438 }
1324 } 1439 }
1325 1440
@@ -1418,14 +1533,17 @@ namespace OpenSim.Region.Framework.Scenes
1418 { 1533 {
1419 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1534 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1420 1535
1421 lock (m_parts) 1536 lockPartsForRead(true);
1422 { 1537 {
1423 foreach (SceneObjectPart part in m_parts.Values) 1538 foreach (SceneObjectPart part in m_parts.Values)
1424 { 1539 {
1540
1425 if (part != RootPart) 1541 if (part != RootPart)
1426 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1542 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1543
1427 } 1544 }
1428 } 1545 }
1546 lockPartsForRead(false);
1429 } 1547 }
1430 1548
1431 /// <summary> 1549 /// <summary>
@@ -1520,10 +1638,11 @@ namespace OpenSim.Region.Framework.Scenes
1520 1638
1521 List<SceneObjectPart> partList; 1639 List<SceneObjectPart> partList;
1522 1640
1523 lock (m_parts) 1641 lockPartsForRead(true);
1524 { 1642
1525 partList = new List<SceneObjectPart>(m_parts.Values); 1643 partList = new List<SceneObjectPart>(m_parts.Values);
1526 } 1644
1645 lockPartsForRead(false);
1527 1646
1528 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1647 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1529 { 1648 {
@@ -1772,6 +1891,7 @@ namespace OpenSim.Region.Framework.Scenes
1772 } 1891 }
1773 } 1892 }
1774 } 1893 }
1894
1775 public void stopLookAt() 1895 public void stopLookAt()
1776 { 1896 {
1777 SceneObjectPart rootpart = m_rootPart; 1897 SceneObjectPart rootpart = m_rootPart;
@@ -1846,10 +1966,11 @@ namespace OpenSim.Region.Framework.Scenes
1846 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1966 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1847 newPart.SetParent(this); 1967 newPart.SetParent(this);
1848 1968
1849 lock (m_parts) 1969 lockPartsForWrite(true);
1850 { 1970 {
1851 m_parts.Add(newPart.UUID, newPart); 1971 m_parts.Add(newPart.UUID, newPart);
1852 } 1972 }
1973 lockPartsForWrite(false);
1853 1974
1854 SetPartAsNonRoot(newPart); 1975 SetPartAsNonRoot(newPart);
1855 1976
@@ -1912,7 +2033,7 @@ namespace OpenSim.Region.Framework.Scenes
1912 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2033 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1913 // return; 2034 // return;
1914 2035
1915 lock (m_parts) 2036 lockPartsForRead(true);
1916 { 2037 {
1917 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2038 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1918 2039
@@ -1930,34 +2051,43 @@ namespace OpenSim.Region.Framework.Scenes
1930 2051
1931 foreach (SceneObjectPart part in m_parts.Values) 2052 foreach (SceneObjectPart part in m_parts.Values)
1932 { 2053 {
2054
1933 part.SendScheduledUpdates(); 2055 part.SendScheduledUpdates();
2056
1934 } 2057 }
1935 } 2058 }
2059 lockPartsForRead(false);
1936 } 2060 }
1937 2061
1938 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2062 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1939 { 2063 {
1940 RootPart.AddFullUpdateToAvatar(presence); 2064 RootPart.AddFullUpdateToAvatar(presence);
1941 2065
1942 lock (m_parts) 2066 lockPartsForRead(true);
1943 { 2067 {
1944 foreach (SceneObjectPart part in m_parts.Values) 2068 foreach (SceneObjectPart part in m_parts.Values)
1945 { 2069 {
2070
1946 if (part != RootPart) 2071 if (part != RootPart)
1947 part.AddFullUpdateToAvatar(presence); 2072 part.AddFullUpdateToAvatar(presence);
2073
1948 } 2074 }
1949 } 2075 }
2076 lockPartsForRead(false);
1950 } 2077 }
1951 2078
1952 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2079 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1953 { 2080 {
1954 lock (m_parts) 2081 lockPartsForRead(true);
1955 { 2082 {
1956 foreach (SceneObjectPart part in m_parts.Values) 2083 foreach (SceneObjectPart part in m_parts.Values)
1957 { 2084 {
2085
1958 part.AddTerseUpdateToAvatar(presence); 2086 part.AddTerseUpdateToAvatar(presence);
2087
1959 } 2088 }
1960 } 2089 }
2090 lockPartsForRead(false);
1961 } 2091 }
1962 2092
1963 /// <summary> 2093 /// <summary>
@@ -1968,14 +2098,17 @@ namespace OpenSim.Region.Framework.Scenes
1968 checkAtTargets(); 2098 checkAtTargets();
1969 RootPart.ScheduleFullUpdate(); 2099 RootPart.ScheduleFullUpdate();
1970 2100
1971 lock (m_parts) 2101 lockPartsForRead(true);
1972 { 2102 {
1973 foreach (SceneObjectPart part in m_parts.Values) 2103 foreach (SceneObjectPart part in m_parts.Values)
1974 { 2104 {
2105
1975 if (part != RootPart) 2106 if (part != RootPart)
1976 part.ScheduleFullUpdate(); 2107 part.ScheduleFullUpdate();
2108
1977 } 2109 }
1978 } 2110 }
2111 lockPartsForRead(false);
1979 } 2112 }
1980 2113
1981 /// <summary> 2114 /// <summary>
@@ -1983,13 +2116,16 @@ namespace OpenSim.Region.Framework.Scenes
1983 /// </summary> 2116 /// </summary>
1984 public void ScheduleGroupForTerseUpdate() 2117 public void ScheduleGroupForTerseUpdate()
1985 { 2118 {
1986 lock (m_parts) 2119 lockPartsForRead(true);
1987 { 2120 {
1988 foreach (SceneObjectPart part in m_parts.Values) 2121 foreach (SceneObjectPart part in m_parts.Values)
1989 { 2122 {
2123
1990 part.ScheduleTerseUpdate(); 2124 part.ScheduleTerseUpdate();
2125
1991 } 2126 }
1992 } 2127 }
2128 lockPartsForRead(false);
1993 } 2129 }
1994 2130
1995 /// <summary> 2131 /// <summary>
@@ -2002,14 +2138,17 @@ namespace OpenSim.Region.Framework.Scenes
2002 2138
2003 RootPart.SendFullUpdateToAllClients(); 2139 RootPart.SendFullUpdateToAllClients();
2004 2140
2005 lock (m_parts) 2141 lockPartsForRead(true);
2006 { 2142 {
2007 foreach (SceneObjectPart part in m_parts.Values) 2143 foreach (SceneObjectPart part in m_parts.Values)
2008 { 2144 {
2145
2009 if (part != RootPart) 2146 if (part != RootPart)
2010 part.SendFullUpdateToAllClients(); 2147 part.SendFullUpdateToAllClients();
2148
2011 } 2149 }
2012 } 2150 }
2151 lockPartsForRead(false);
2013 } 2152 }
2014 2153
2015 /// <summary> 2154 /// <summary>
@@ -2040,14 +2179,15 @@ namespace OpenSim.Region.Framework.Scenes
2040 { 2179 {
2041 if (IsDeleted) 2180 if (IsDeleted)
2042 return; 2181 return;
2043 2182
2044 lock (m_parts) 2183 lockPartsForRead(true);
2045 { 2184 {
2046 foreach (SceneObjectPart part in m_parts.Values) 2185 foreach (SceneObjectPart part in m_parts.Values)
2047 { 2186 {
2048 part.SendTerseUpdateToAllClients(); 2187 part.SendTerseUpdateToAllClients();
2049 } 2188 }
2050 } 2189 }
2190 lockPartsForRead(false);
2051 } 2191 }
2052 2192
2053 #endregion 2193 #endregion
@@ -2061,16 +2201,18 @@ namespace OpenSim.Region.Framework.Scenes
2061 /// <returns>null if no child part with that linknum or child part</returns> 2201 /// <returns>null if no child part with that linknum or child part</returns>
2062 public SceneObjectPart GetLinkNumPart(int linknum) 2202 public SceneObjectPart GetLinkNumPart(int linknum)
2063 { 2203 {
2064 lock (m_parts) 2204 lockPartsForRead(true);
2065 { 2205 {
2066 foreach (SceneObjectPart part in m_parts.Values) 2206 foreach (SceneObjectPart part in m_parts.Values)
2067 { 2207 {
2068 if (part.LinkNum == linknum) 2208 if (part.LinkNum == linknum)
2069 { 2209 {
2210 lockPartsForRead(false);
2070 return part; 2211 return part;
2071 } 2212 }
2072 } 2213 }
2073 } 2214 }
2215 lockPartsForRead(false);
2074 2216
2075 return null; 2217 return null;
2076 } 2218 }
@@ -2098,17 +2240,19 @@ namespace OpenSim.Region.Framework.Scenes
2098 public SceneObjectPart GetChildPart(uint localID) 2240 public SceneObjectPart GetChildPart(uint localID)
2099 { 2241 {
2100 //m_log.DebugFormat("Entered looking for {0}", localID); 2242 //m_log.DebugFormat("Entered looking for {0}", localID);
2101 lock (m_parts) 2243 lockPartsForRead(true);
2102 { 2244 {
2103 foreach (SceneObjectPart part in m_parts.Values) 2245 foreach (SceneObjectPart part in m_parts.Values)
2104 { 2246 {
2105 //m_log.DebugFormat("Found {0}", part.LocalId); 2247 //m_log.DebugFormat("Found {0}", part.LocalId);
2106 if (part.LocalId == localID) 2248 if (part.LocalId == localID)
2107 { 2249 {
2250 lockPartsForRead(false);
2108 return part; 2251 return part;
2109 } 2252 }
2110 } 2253 }
2111 } 2254 }
2255 lockPartsForRead(false);
2112 2256
2113 return null; 2257 return null;
2114 } 2258 }
@@ -2138,17 +2282,19 @@ namespace OpenSim.Region.Framework.Scenes
2138 public bool HasChildPrim(uint localID) 2282 public bool HasChildPrim(uint localID)
2139 { 2283 {
2140 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2284 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2141 lock (m_parts) 2285 lockPartsForRead(true);
2142 { 2286 {
2143 foreach (SceneObjectPart part in m_parts.Values) 2287 foreach (SceneObjectPart part in m_parts.Values)
2144 { 2288 {
2145 //m_log.DebugFormat("Found {0}", part.LocalId); 2289 //m_log.DebugFormat("Found {0}", part.LocalId);
2146 if (part.LocalId == localID) 2290 if (part.LocalId == localID)
2147 { 2291 {
2292 lockPartsForRead(false);
2148 return true; 2293 return true;
2149 } 2294 }
2150 } 2295 }
2151 } 2296 }
2297 lockPartsForRead(false);
2152 2298
2153 return false; 2299 return false;
2154 } 2300 }
@@ -2198,53 +2344,57 @@ namespace OpenSim.Region.Framework.Scenes
2198 if (m_rootPart.LinkNum == 0) 2344 if (m_rootPart.LinkNum == 0)
2199 m_rootPart.LinkNum = 1; 2345 m_rootPart.LinkNum = 1;
2200 2346
2201 lock (m_parts) 2347 lockPartsForWrite(true);
2202 { 2348
2203 m_parts.Add(linkPart.UUID, linkPart); 2349 m_parts.Add(linkPart.UUID, linkPart);
2204 2350
2205 // Insert in terms of link numbers, the new links 2351 lockPartsForWrite(false);
2206 // before the current ones (with the exception of 2352
2207 // the root prim. Shuffle the old ones up 2353 // Insert in terms of link numbers, the new links
2208 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2354 // before the current ones (with the exception of
2355 // the root prim. Shuffle the old ones up
2356 lockPartsForRead(true);
2357 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2358 {
2359 if (kvp.Value.LinkNum != 1)
2209 { 2360 {
2210 if (kvp.Value.LinkNum != 1) 2361 // Don't update root prim link number
2211 { 2362 kvp.Value.LinkNum += objectGroup.PrimCount;
2212 // Don't update root prim link number
2213 kvp.Value.LinkNum += objectGroup.PrimCount;
2214 }
2215 } 2363 }
2364 }
2365 lockPartsForRead(false);
2216 2366
2217 linkPart.LinkNum = 2; 2367 linkPart.LinkNum = 2;
2218 2368
2219 linkPart.SetParent(this); 2369 linkPart.SetParent(this);
2220 linkPart.AddFlag(PrimFlags.CreateSelected); 2370 linkPart.AddFlag(PrimFlags.CreateSelected);
2221 2371
2222 //if (linkPart.PhysActor != null) 2372 //if (linkPart.PhysActor != null)
2223 //{ 2373 //{
2224 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2374 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2225 2375
2226 //linkPart.PhysActor = null; 2376 //linkPart.PhysActor = null;
2227 //} 2377 //}
2228 2378
2229 //TODO: rest of parts 2379 //TODO: rest of parts
2230 int linkNum = 3; 2380 int linkNum = 3;
2231 foreach (SceneObjectPart part in objectGroup.Children.Values) 2381 foreach (SceneObjectPart part in objectGroup.Children.Values)
2382 {
2383 if (part.UUID != objectGroup.m_rootPart.UUID)
2232 { 2384 {
2233 if (part.UUID != objectGroup.m_rootPart.UUID) 2385 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2234 {
2235 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2236 }
2237 part.ClearUndoState();
2238 } 2386 }
2387 part.ClearUndoState();
2239 } 2388 }
2240 2389
2241 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2390 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2242 objectGroup.m_isDeleted = true; 2391 objectGroup.m_isDeleted = true;
2392
2393 objectGroup.lockPartsForWrite(true);
2243 2394
2244 lock (objectGroup.m_parts) 2395 objectGroup.m_parts.Clear();
2245 { 2396
2246 objectGroup.m_parts.Clear(); 2397 objectGroup.lockPartsForWrite(false);
2247 }
2248 2398
2249 // Can't do this yet since backup still makes use of the root part without any synchronization 2399 // Can't do this yet since backup still makes use of the root part without any synchronization
2250// objectGroup.m_rootPart = null; 2400// objectGroup.m_rootPart = null;
@@ -2303,11 +2453,12 @@ namespace OpenSim.Region.Framework.Scenes
2303 Quaternion worldRot = linkPart.GetWorldRotation(); 2453 Quaternion worldRot = linkPart.GetWorldRotation();
2304 2454
2305 // Remove the part from this object 2455 // Remove the part from this object
2306 lock (m_parts) 2456 lockPartsForWrite(true);
2307 { 2457 {
2308 m_parts.Remove(linkPart.UUID); 2458 m_parts.Remove(linkPart.UUID);
2309 } 2459 }
2310 2460 lockPartsForWrite(false);
2461 lockPartsForRead(true);
2311 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2462 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2312 RootPart.LinkNum = 0; 2463 RootPart.LinkNum = 0;
2313 else 2464 else
@@ -2318,6 +2469,7 @@ namespace OpenSim.Region.Framework.Scenes
2318 p.LinkNum--; 2469 p.LinkNum--;
2319 } 2470 }
2320 } 2471 }
2472 lockPartsForRead(false);
2321 2473
2322 linkPart.ParentID = 0; 2474 linkPart.ParentID = 0;
2323 linkPart.LinkNum = 0; 2475 linkPart.LinkNum = 0;
@@ -2635,9 +2787,12 @@ namespace OpenSim.Region.Framework.Scenes
2635 2787
2636 if (selectionPart != null) 2788 if (selectionPart != null)
2637 { 2789 {
2638 lock (m_parts) 2790 lockPartsForRead(true);
2791 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2792 lockPartsForRead(false);
2793 foreach (SceneObjectPart part in parts)
2639 { 2794 {
2640 foreach (SceneObjectPart part in m_parts.Values) 2795 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2641 { 2796 {
2642 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2797 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2643 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2798 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2647,12 +2802,13 @@ namespace OpenSim.Region.Framework.Scenes
2647 break; 2802 break;
2648 } 2803 }
2649 } 2804 }
2805 }
2650 2806
2651 foreach (SceneObjectPart part in m_parts.Values) 2807 foreach (SceneObjectPart part in parts)
2652 { 2808 {
2653 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2809 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2654 }
2655 } 2810 }
2811
2656 } 2812 }
2657 } 2813 }
2658 2814
@@ -2738,11 +2894,9 @@ namespace OpenSim.Region.Framework.Scenes
2738 scale.Y = m_scene.m_maxNonphys; 2894 scale.Y = m_scene.m_maxNonphys;
2739 if (scale.Z > m_scene.m_maxNonphys) 2895 if (scale.Z > m_scene.m_maxNonphys)
2740 scale.Z = m_scene.m_maxNonphys; 2896 scale.Z = m_scene.m_maxNonphys;
2741
2742 SceneObjectPart part = GetChildPart(localID); 2897 SceneObjectPart part = GetChildPart(localID);
2743 if (part != null) 2898 if (part != null)
2744 { 2899 {
2745 part.Resize(scale);
2746 if (part.PhysActor != null) 2900 if (part.PhysActor != null)
2747 { 2901 {
2748 if (part.PhysActor.IsPhysical) 2902 if (part.PhysActor.IsPhysical)
@@ -2757,7 +2911,7 @@ namespace OpenSim.Region.Framework.Scenes
2757 part.PhysActor.Size = scale; 2911 part.PhysActor.Size = scale;
2758 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2912 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2759 } 2913 }
2760 //if (part.UUID != m_rootPart.UUID) 2914 part.Resize(scale);
2761 2915
2762 HasGroupChanged = true; 2916 HasGroupChanged = true;
2763 ScheduleGroupForFullUpdate(); 2917 ScheduleGroupForFullUpdate();
@@ -2798,77 +2952,76 @@ namespace OpenSim.Region.Framework.Scenes
2798 float y = (scale.Y / part.Scale.Y); 2952 float y = (scale.Y / part.Scale.Y);
2799 float z = (scale.Z / part.Scale.Z); 2953 float z = (scale.Z / part.Scale.Z);
2800 2954
2801 lock (m_parts) 2955 lockPartsForRead(true);
2956 if (x > 1.0f || y > 1.0f || z > 1.0f)
2802 { 2957 {
2803 if (x > 1.0f || y > 1.0f || z > 1.0f) 2958 foreach (SceneObjectPart obPart in m_parts.Values)
2804 { 2959 {
2805 foreach (SceneObjectPart obPart in m_parts.Values) 2960 if (obPart.UUID != m_rootPart.UUID)
2806 { 2961 {
2807 if (obPart.UUID != m_rootPart.UUID) 2962 Vector3 oldSize = new Vector3(obPart.Scale);
2808 {
2809 Vector3 oldSize = new Vector3(obPart.Scale);
2810 2963
2811 float f = 1.0f; 2964 float f = 1.0f;
2812 float a = 1.0f; 2965 float a = 1.0f;
2813 2966
2814 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2967 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2968 {
2969 if (oldSize.X*x > m_scene.m_maxPhys)
2815 { 2970 {
2816 if (oldSize.X*x > m_scene.m_maxPhys) 2971 f = m_scene.m_maxPhys / oldSize.X;
2817 { 2972 a = f / x;
2818 f = m_scene.m_maxPhys / oldSize.X; 2973 x *= a;
2819 a = f / x; 2974 y *= a;
2820 x *= a; 2975 z *= a;
2821 y *= a;
2822 z *= a;
2823 }
2824 if (oldSize.Y*y > m_scene.m_maxPhys)
2825 {
2826 f = m_scene.m_maxPhys / oldSize.Y;
2827 a = f / y;
2828 x *= a;
2829 y *= a;
2830 z *= a;
2831 }
2832 if (oldSize.Z*z > m_scene.m_maxPhys)
2833 {
2834 f = m_scene.m_maxPhys / oldSize.Z;
2835 a = f / z;
2836 x *= a;
2837 y *= a;
2838 z *= a;
2839 }
2840 } 2976 }
2841 else 2977 if (oldSize.Y*y > m_scene.m_maxPhys)
2978 {
2979 f = m_scene.m_maxPhys / oldSize.Y;
2980 a = f / y;
2981 x *= a;
2982 y *= a;
2983 z *= a;
2984 }
2985 if (oldSize.Z*z > m_scene.m_maxPhys)
2986 {
2987 f = m_scene.m_maxPhys / oldSize.Z;
2988 a = f / z;
2989 x *= a;
2990 y *= a;
2991 z *= a;
2992 }
2993 }
2994 else
2995 {
2996 if (oldSize.X*x > m_scene.m_maxNonphys)
2997 {
2998 f = m_scene.m_maxNonphys / oldSize.X;
2999 a = f / x;
3000 x *= a;
3001 y *= a;
3002 z *= a;
3003 }
3004 if (oldSize.Y*y > m_scene.m_maxNonphys)
2842 { 3005 {
2843 if (oldSize.X*x > m_scene.m_maxNonphys) 3006 f = m_scene.m_maxNonphys / oldSize.Y;
2844 { 3007 a = f / y;
2845 f = m_scene.m_maxNonphys / oldSize.X; 3008 x *= a;
2846 a = f / x; 3009 y *= a;
2847 x *= a; 3010 z *= a;
2848 y *= a; 3011 }
2849 z *= a; 3012 if (oldSize.Z*z > m_scene.m_maxNonphys)
2850 } 3013 {
2851 if (oldSize.Y*y > m_scene.m_maxNonphys) 3014 f = m_scene.m_maxNonphys / oldSize.Z;
2852 { 3015 a = f / z;
2853 f = m_scene.m_maxNonphys / oldSize.Y; 3016 x *= a;
2854 a = f / y; 3017 y *= a;
2855 x *= a; 3018 z *= a;
2856 y *= a;
2857 z *= a;
2858 }
2859 if (oldSize.Z*z > m_scene.m_maxNonphys)
2860 {
2861 f = m_scene.m_maxNonphys / oldSize.Z;
2862 a = f / z;
2863 x *= a;
2864 y *= a;
2865 z *= a;
2866 }
2867 } 3019 }
2868 } 3020 }
2869 } 3021 }
2870 } 3022 }
2871 } 3023 }
3024 lockPartsForRead(false);
2872 3025
2873 Vector3 prevScale = part.Scale; 3026 Vector3 prevScale = part.Scale;
2874 prevScale.X *= x; 3027 prevScale.X *= x;
@@ -2876,7 +3029,7 @@ namespace OpenSim.Region.Framework.Scenes
2876 prevScale.Z *= z; 3029 prevScale.Z *= z;
2877 part.Resize(prevScale); 3030 part.Resize(prevScale);
2878 3031
2879 lock (m_parts) 3032 lockPartsForRead(true);
2880 { 3033 {
2881 foreach (SceneObjectPart obPart in m_parts.Values) 3034 foreach (SceneObjectPart obPart in m_parts.Values)
2882 { 3035 {
@@ -2895,6 +3048,7 @@ namespace OpenSim.Region.Framework.Scenes
2895 } 3048 }
2896 } 3049 }
2897 } 3050 }
3051 lockPartsForRead(false);
2898 3052
2899 if (part.PhysActor != null) 3053 if (part.PhysActor != null)
2900 { 3054 {
@@ -2975,7 +3129,7 @@ namespace OpenSim.Region.Framework.Scenes
2975 axDiff *= Quaternion.Inverse(partRotation); 3129 axDiff *= Quaternion.Inverse(partRotation);
2976 diff = axDiff; 3130 diff = axDiff;
2977 3131
2978 lock (m_parts) 3132 lockPartsForRead(true);
2979 { 3133 {
2980 foreach (SceneObjectPart obPart in m_parts.Values) 3134 foreach (SceneObjectPart obPart in m_parts.Values)
2981 { 3135 {
@@ -2985,6 +3139,7 @@ namespace OpenSim.Region.Framework.Scenes
2985 } 3139 }
2986 } 3140 }
2987 } 3141 }
3142 lockPartsForRead(false);
2988 3143
2989 AbsolutePosition = newPos; 3144 AbsolutePosition = newPos;
2990 3145
@@ -3102,7 +3257,7 @@ namespace OpenSim.Region.Framework.Scenes
3102 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3257 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3103 } 3258 }
3104 3259
3105 lock (m_parts) 3260 lockPartsForRead(true);
3106 { 3261 {
3107 foreach (SceneObjectPart prim in m_parts.Values) 3262 foreach (SceneObjectPart prim in m_parts.Values)
3108 { 3263 {
@@ -3120,6 +3275,7 @@ namespace OpenSim.Region.Framework.Scenes
3120 } 3275 }
3121 } 3276 }
3122 } 3277 }
3278 lockPartsForRead(false);
3123 3279
3124 m_rootPart.ScheduleTerseUpdate(); 3280 m_rootPart.ScheduleTerseUpdate();
3125 } 3281 }
@@ -3218,7 +3374,7 @@ namespace OpenSim.Region.Framework.Scenes
3218 if (atTargets.Count > 0) 3374 if (atTargets.Count > 0)
3219 { 3375 {
3220 uint[] localids = new uint[0]; 3376 uint[] localids = new uint[0];
3221 lock (m_parts) 3377 lockPartsForRead(true);
3222 { 3378 {
3223 localids = new uint[m_parts.Count]; 3379 localids = new uint[m_parts.Count];
3224 int cntr = 0; 3380 int cntr = 0;
@@ -3228,6 +3384,7 @@ namespace OpenSim.Region.Framework.Scenes
3228 cntr++; 3384 cntr++;
3229 } 3385 }
3230 } 3386 }
3387 lockPartsForRead(false);
3231 3388
3232 for (int ctr = 0; ctr < localids.Length; ctr++) 3389 for (int ctr = 0; ctr < localids.Length; ctr++)
3233 { 3390 {
@@ -3246,7 +3403,7 @@ namespace OpenSim.Region.Framework.Scenes
3246 { 3403 {
3247 //trigger not_at_target 3404 //trigger not_at_target
3248 uint[] localids = new uint[0]; 3405 uint[] localids = new uint[0];
3249 lock (m_parts) 3406 lockPartsForRead(true);
3250 { 3407 {
3251 localids = new uint[m_parts.Count]; 3408 localids = new uint[m_parts.Count];
3252 int cntr = 0; 3409 int cntr = 0;
@@ -3256,7 +3413,8 @@ namespace OpenSim.Region.Framework.Scenes
3256 cntr++; 3413 cntr++;
3257 } 3414 }
3258 } 3415 }
3259 3416 lockPartsForRead(false);
3417
3260 for (int ctr = 0; ctr < localids.Length; ctr++) 3418 for (int ctr = 0; ctr < localids.Length; ctr++)
3261 { 3419 {
3262 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3420 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3269,19 +3427,20 @@ namespace OpenSim.Region.Framework.Scenes
3269 public float GetMass() 3427 public float GetMass()
3270 { 3428 {
3271 float retmass = 0f; 3429 float retmass = 0f;
3272 lock (m_parts) 3430 lockPartsForRead(true);
3273 { 3431 {
3274 foreach (SceneObjectPart part in m_parts.Values) 3432 foreach (SceneObjectPart part in m_parts.Values)
3275 { 3433 {
3276 retmass += part.GetMass(); 3434 retmass += part.GetMass();
3277 } 3435 }
3278 } 3436 }
3437 lockPartsForRead(false);
3279 return retmass; 3438 return retmass;
3280 } 3439 }
3281 3440
3282 public void CheckSculptAndLoad() 3441 public void CheckSculptAndLoad()
3283 { 3442 {
3284 lock (m_parts) 3443 lockPartsForRead(true);
3285 { 3444 {
3286 if (!IsDeleted) 3445 if (!IsDeleted)
3287 { 3446 {
@@ -3306,6 +3465,7 @@ namespace OpenSim.Region.Framework.Scenes
3306 } 3465 }
3307 } 3466 }
3308 } 3467 }
3468 lockPartsForRead(false);
3309 } 3469 }
3310 3470
3311 protected void AssetReceived(string id, Object sender, AssetBase asset) 3471 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3326,7 +3486,7 @@ namespace OpenSim.Region.Framework.Scenes
3326 /// <param name="client"></param> 3486 /// <param name="client"></param>
3327 public void SetGroup(UUID GroupID, IClientAPI client) 3487 public void SetGroup(UUID GroupID, IClientAPI client)
3328 { 3488 {
3329 lock (m_parts) 3489 lockPartsForRead(true);
3330 { 3490 {
3331 foreach (SceneObjectPart part in m_parts.Values) 3491 foreach (SceneObjectPart part in m_parts.Values)
3332 { 3492 {
@@ -3336,7 +3496,7 @@ namespace OpenSim.Region.Framework.Scenes
3336 3496
3337 HasGroupChanged = true; 3497 HasGroupChanged = true;
3338 } 3498 }
3339 3499 lockPartsForRead(false);
3340 ScheduleGroupForFullUpdate(); 3500 ScheduleGroupForFullUpdate();
3341 } 3501 }
3342 3502
@@ -3355,11 +3515,12 @@ namespace OpenSim.Region.Framework.Scenes
3355 3515
3356 public void SetAttachmentPoint(byte point) 3516 public void SetAttachmentPoint(byte point)
3357 { 3517 {
3358 lock (m_parts) 3518 lockPartsForRead(true);
3359 { 3519 {
3360 foreach (SceneObjectPart part in m_parts.Values) 3520 foreach (SceneObjectPart part in m_parts.Values)
3361 part.SetAttachmentPoint(point); 3521 part.SetAttachmentPoint(point);
3362 } 3522 }
3523 lockPartsForRead(false);
3363 } 3524 }
3364 3525
3365 #region ISceneObject 3526 #region ISceneObject