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 8050bf6..bc16a93 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 {
@@ -255,13 +321,16 @@ namespace OpenSim.Region.Framework.Scenes
255 set 321 set
256 { 322 {
257 m_regionHandle = value; 323 m_regionHandle = value;
258 lock (m_parts) 324 lockPartsForRead(true);
259 { 325 {
260 foreach (SceneObjectPart part in m_parts.Values) 326 foreach (SceneObjectPart part in m_parts.Values)
261 { 327 {
328
262 part.RegionHandle = m_regionHandle; 329 part.RegionHandle = m_regionHandle;
330
263 } 331 }
264 } 332 }
333 lockPartsForRead(false);
265 } 334 }
266 } 335 }
267 336
@@ -287,13 +356,16 @@ namespace OpenSim.Region.Framework.Scenes
287 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 356 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
288 } 357 }
289 358
290 lock (m_parts) 359 lockPartsForRead(true);
291 { 360 {
292 foreach (SceneObjectPart part in m_parts.Values) 361 foreach (SceneObjectPart part in m_parts.Values)
293 { 362 {
363
294 part.GroupPosition = val; 364 part.GroupPosition = val;
365
295 } 366 }
296 } 367 }
368 lockPartsForRead(false);
297 369
298 //if (m_rootPart.PhysActor != null) 370 //if (m_rootPart.PhysActor != null)
299 //{ 371 //{
@@ -455,13 +527,16 @@ namespace OpenSim.Region.Framework.Scenes
455 527
456 public void SetFromItemID(UUID AssetId) 528 public void SetFromItemID(UUID AssetId)
457 { 529 {
458 lock (m_parts) 530 lockPartsForRead(true);
459 { 531 {
460 foreach (SceneObjectPart part in m_parts.Values) 532 foreach (SceneObjectPart part in m_parts.Values)
461 { 533 {
534
462 part.FromItemID = AssetId; 535 part.FromItemID = AssetId;
536
463 } 537 }
464 } 538 }
539 lockPartsForRead(false);
465 } 540 }
466 541
467 public UUID GetFromItemID() 542 public UUID GetFromItemID()
@@ -528,10 +603,11 @@ namespace OpenSim.Region.Framework.Scenes
528 Vector3 maxScale = Vector3.Zero; 603 Vector3 maxScale = Vector3.Zero;
529 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 604 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
530 605
531 lock (m_parts) 606 lockPartsForRead(true);
532 { 607 {
533 foreach (SceneObjectPart part in m_parts.Values) 608 foreach (SceneObjectPart part in m_parts.Values)
534 { 609 {
610
535 Vector3 partscale = part.Scale; 611 Vector3 partscale = part.Scale;
536 Vector3 partoffset = part.OffsetPosition; 612 Vector3 partoffset = part.OffsetPosition;
537 613
@@ -542,8 +618,11 @@ namespace OpenSim.Region.Framework.Scenes
542 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 618 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
543 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 619 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
544 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 620 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
621
545 } 622 }
546 } 623 }
624 lockPartsForRead(false);
625
547 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 626 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
548 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 627 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
549 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 628 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -559,10 +638,11 @@ namespace OpenSim.Region.Framework.Scenes
559 638
560 EntityIntersection result = new EntityIntersection(); 639 EntityIntersection result = new EntityIntersection();
561 640
562 lock (m_parts) 641 lockPartsForRead(true);
563 { 642 {
564 foreach (SceneObjectPart part in m_parts.Values) 643 foreach (SceneObjectPart part in m_parts.Values)
565 { 644 {
645
566 // Temporary commented to stop compiler warning 646 // Temporary commented to stop compiler warning
567 //Vector3 partPosition = 647 //Vector3 partPosition =
568 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 648 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -590,8 +670,10 @@ namespace OpenSim.Region.Framework.Scenes
590 result.distance = inter.distance; 670 result.distance = inter.distance;
591 } 671 }
592 } 672 }
673
593 } 674 }
594 } 675 }
676 lockPartsForRead(false);
595 return result; 677 return result;
596 } 678 }
597 679
@@ -604,10 +686,11 @@ namespace OpenSim.Region.Framework.Scenes
604 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 686 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
605 { 687 {
606 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 688 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
607 lock (m_parts) 689 lockPartsForRead(true);
608 { 690 {
609 foreach (SceneObjectPart part in m_parts.Values) 691 foreach (SceneObjectPart part in m_parts.Values)
610 { 692 {
693
611 Vector3 worldPos = part.GetWorldPosition(); 694 Vector3 worldPos = part.GetWorldPosition();
612 Vector3 offset = worldPos - AbsolutePosition; 695 Vector3 offset = worldPos - AbsolutePosition;
613 Quaternion worldRot; 696 Quaternion worldRot;
@@ -666,6 +749,8 @@ namespace OpenSim.Region.Framework.Scenes
666 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 749 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
667 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 750 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
668 751
752
753
669 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 754 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
670 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 755 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
671 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 756 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -837,6 +922,7 @@ namespace OpenSim.Region.Framework.Scenes
837 minZ = backBottomLeft.Z; 922 minZ = backBottomLeft.Z;
838 } 923 }
839 } 924 }
925 lockPartsForRead(false);
840 926
841 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 927 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
842 928
@@ -865,17 +951,20 @@ namespace OpenSim.Region.Framework.Scenes
865 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 951 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
866 952
867 // Capture script state while holding the lock 953 // Capture script state while holding the lock
868 lock (m_parts) 954 lockPartsForRead(true);
869 { 955 {
870 foreach (SceneObjectPart part in m_parts.Values) 956 foreach (SceneObjectPart part in m_parts.Values)
871 { 957 {
958
872 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 959 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
873 foreach (UUID itemid in pstates.Keys) 960 foreach (UUID itemid in pstates.Keys)
874 { 961 {
875 states.Add(itemid, pstates[itemid]); 962 states.Add(itemid, pstates[itemid]);
876 } 963 }
964
877 } 965 }
878 } 966 }
967 lockPartsForRead(false);
879 968
880 if (states.Count > 0) 969 if (states.Count > 0)
881 { 970 {
@@ -1037,13 +1126,16 @@ namespace OpenSim.Region.Framework.Scenes
1037 1126
1038 public override void UpdateMovement() 1127 public override void UpdateMovement()
1039 { 1128 {
1040 lock (m_parts) 1129 lockPartsForRead(true);
1041 { 1130 {
1042 foreach (SceneObjectPart part in m_parts.Values) 1131 foreach (SceneObjectPart part in m_parts.Values)
1043 { 1132 {
1133
1044 part.UpdateMovement(); 1134 part.UpdateMovement();
1135
1045 } 1136 }
1046 } 1137 }
1138 lockPartsForRead(false);
1047 } 1139 }
1048 1140
1049 public ushort GetTimeDilation() 1141 public ushort GetTimeDilation()
@@ -1087,7 +1179,7 @@ namespace OpenSim.Region.Framework.Scenes
1087 /// <param name="part"></param> 1179 /// <param name="part"></param>
1088 public void AddPart(SceneObjectPart part) 1180 public void AddPart(SceneObjectPart part)
1089 { 1181 {
1090 lock (m_parts) 1182 lockPartsForWrite(true);
1091 { 1183 {
1092 part.SetParent(this); 1184 part.SetParent(this);
1093 m_parts.Add(part.UUID, part); 1185 m_parts.Add(part.UUID, part);
@@ -1097,6 +1189,7 @@ namespace OpenSim.Region.Framework.Scenes
1097 if (part.LinkNum == 2 && RootPart != null) 1189 if (part.LinkNum == 2 && RootPart != null)
1098 RootPart.LinkNum = 1; 1190 RootPart.LinkNum = 1;
1099 } 1191 }
1192 lockPartsForWrite(false);
1100 } 1193 }
1101 1194
1102 /// <summary> 1195 /// <summary>
@@ -1104,28 +1197,33 @@ namespace OpenSim.Region.Framework.Scenes
1104 /// </summary> 1197 /// </summary>
1105 private void UpdateParentIDs() 1198 private void UpdateParentIDs()
1106 { 1199 {
1107 lock (m_parts) 1200 lockPartsForRead(true);
1108 { 1201 {
1109 foreach (SceneObjectPart part in m_parts.Values) 1202 foreach (SceneObjectPart part in m_parts.Values)
1110 { 1203 {
1204
1111 if (part.UUID != m_rootPart.UUID) 1205 if (part.UUID != m_rootPart.UUID)
1112 { 1206 {
1113 part.ParentID = m_rootPart.LocalId; 1207 part.ParentID = m_rootPart.LocalId;
1114 } 1208 }
1209
1115 } 1210 }
1116 } 1211 }
1212 lockPartsForRead(false);
1117 } 1213 }
1118 1214
1119 public void RegenerateFullIDs() 1215 public void RegenerateFullIDs()
1120 { 1216 {
1121 lock (m_parts) 1217 lockPartsForRead(true);
1122 { 1218 {
1123 foreach (SceneObjectPart part in m_parts.Values) 1219 foreach (SceneObjectPart part in m_parts.Values)
1124 { 1220 {
1221
1125 part.UUID = UUID.Random(); 1222 part.UUID = UUID.Random();
1126 1223
1127 } 1224 }
1128 } 1225 }
1226 lockPartsForRead(false);
1129 } 1227 }
1130 1228
1131 // helper provided for parts. 1229 // helper provided for parts.
@@ -1206,29 +1304,33 @@ namespace OpenSim.Region.Framework.Scenes
1206 1304
1207 DetachFromBackup(); 1305 DetachFromBackup();
1208 1306
1209 lock (m_parts) 1307 lockPartsForRead(true);
1308 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1309 lockPartsForRead(false);
1310
1311 foreach (SceneObjectPart part in values)
1210 { 1312 {
1211 foreach (SceneObjectPart part in m_parts.Values)
1212 {
1213// part.Inventory.RemoveScriptInstances(); 1313// part.Inventory.RemoveScriptInstances();
1214 1314
1215 ScenePresence[] avatars = Scene.GetScenePresences(); 1315 ScenePresence[] avatars = Scene.GetScenePresences();
1216 for (int i = 0; i < avatars.Length; i++) 1316 for (int i = 0; i < avatars.Length; i++)
1317 {
1318 if (avatars[i].ParentID == LocalId)
1217 { 1319 {
1218 if (avatars[i].ParentID == LocalId) 1320 avatars[i].StandUp();
1219 { 1321 }
1220 avatars[i].StandUp();
1221 }
1222 1322
1223 if (!silent) 1323 if (!silent)
1224 { 1324 {
1225 part.UpdateFlag = 0; 1325 part.UpdateFlag = 0;
1226 if (part == m_rootPart) 1326 if (part == m_rootPart)
1227 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1327 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1228 }
1229 } 1328 }
1230 } 1329 }
1330
1231 } 1331 }
1332
1333
1232 } 1334 }
1233 1335
1234 public void AddScriptLPS(int count) 1336 public void AddScriptLPS(int count)
@@ -1253,17 +1355,20 @@ namespace OpenSim.Region.Framework.Scenes
1253 1355
1254 scriptEvents aggregateScriptEvents=0; 1356 scriptEvents aggregateScriptEvents=0;
1255 1357
1256 lock (m_parts) 1358 lockPartsForRead(true);
1257 { 1359 {
1258 foreach (SceneObjectPart part in m_parts.Values) 1360 foreach (SceneObjectPart part in m_parts.Values)
1259 { 1361 {
1362
1260 if (part == null) 1363 if (part == null)
1261 continue; 1364 continue;
1262 if (part != RootPart) 1365 if (part != RootPart)
1263 part.ObjectFlags = objectflagupdate; 1366 part.ObjectFlags = objectflagupdate;
1264 aggregateScriptEvents |= part.AggregateScriptEvents; 1367 aggregateScriptEvents |= part.AggregateScriptEvents;
1368
1265 } 1369 }
1266 } 1370 }
1371 lockPartsForRead(false);
1267 1372
1268 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1373 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1269 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1374 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1305,42 +1410,52 @@ namespace OpenSim.Region.Framework.Scenes
1305 /// <param name="m_physicalPrim"></param> 1410 /// <param name="m_physicalPrim"></param>
1306 public void ApplyPhysics(bool m_physicalPrim) 1411 public void ApplyPhysics(bool m_physicalPrim)
1307 { 1412 {
1308 lock (m_parts) 1413 lockPartsForRead(true);
1414
1415 if (m_parts.Count > 1)
1309 { 1416 {
1310 if (m_parts.Count > 1) 1417 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1418 lockPartsForRead(false);
1419 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1420 foreach (SceneObjectPart part in values)
1311 { 1421 {
1312 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1422
1313 foreach (SceneObjectPart part in m_parts.Values) 1423 if (part.LocalId != m_rootPart.LocalId)
1314 { 1424 {
1315 if (part.LocalId != m_rootPart.LocalId) 1425 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1316 {
1317 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1318 }
1319 } 1426 }
1320 1427
1321 // Hack to get the physics scene geometries in the right spot
1322 ResetChildPrimPhysicsPositions();
1323 }
1324 else
1325 {
1326 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1327 } 1428 }
1429 // Hack to get the physics scene geometries in the right spot
1430 ResetChildPrimPhysicsPositions();
1431 }
1432 else
1433 {
1434 lockPartsForRead(false);
1435 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1328 } 1436 }
1329 } 1437 }
1330 1438
1331 public void SetOwnerId(UUID userId) 1439 public void SetOwnerId(UUID userId)
1332 { 1440 {
1333 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1441 ForEachPart(delegate(SceneObjectPart part)
1442 {
1443
1444 part.OwnerID = userId;
1445
1446 });
1334 } 1447 }
1335 1448
1336 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1449 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1337 { 1450 {
1338 lock (m_parts) 1451 lockPartsForRead(true);
1452 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1453 lockPartsForRead(false);
1454 foreach (SceneObjectPart part in values)
1339 { 1455 {
1340 foreach (SceneObjectPart part in m_parts.Values) 1456
1341 { 1457 whatToDo(part);
1342 whatToDo(part); 1458
1343 }
1344 } 1459 }
1345 } 1460 }
1346 1461
@@ -1439,14 +1554,17 @@ namespace OpenSim.Region.Framework.Scenes
1439 { 1554 {
1440 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1555 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1441 1556
1442 lock (m_parts) 1557 lockPartsForRead(true);
1443 { 1558 {
1444 foreach (SceneObjectPart part in m_parts.Values) 1559 foreach (SceneObjectPart part in m_parts.Values)
1445 { 1560 {
1561
1446 if (part != RootPart) 1562 if (part != RootPart)
1447 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1563 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1564
1448 } 1565 }
1449 } 1566 }
1567 lockPartsForRead(false);
1450 } 1568 }
1451 1569
1452 /// <summary> 1570 /// <summary>
@@ -1541,10 +1659,11 @@ namespace OpenSim.Region.Framework.Scenes
1541 1659
1542 List<SceneObjectPart> partList; 1660 List<SceneObjectPart> partList;
1543 1661
1544 lock (m_parts) 1662 lockPartsForRead(true);
1545 { 1663
1546 partList = new List<SceneObjectPart>(m_parts.Values); 1664 partList = new List<SceneObjectPart>(m_parts.Values);
1547 } 1665
1666 lockPartsForRead(false);
1548 1667
1549 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1668 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1550 { 1669 {
@@ -1793,6 +1912,7 @@ namespace OpenSim.Region.Framework.Scenes
1793 } 1912 }
1794 } 1913 }
1795 } 1914 }
1915
1796 public void stopLookAt() 1916 public void stopLookAt()
1797 { 1917 {
1798 SceneObjectPart rootpart = m_rootPart; 1918 SceneObjectPart rootpart = m_rootPart;
@@ -1867,10 +1987,11 @@ namespace OpenSim.Region.Framework.Scenes
1867 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1987 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1868 newPart.SetParent(this); 1988 newPart.SetParent(this);
1869 1989
1870 lock (m_parts) 1990 lockPartsForWrite(true);
1871 { 1991 {
1872 m_parts.Add(newPart.UUID, newPart); 1992 m_parts.Add(newPart.UUID, newPart);
1873 } 1993 }
1994 lockPartsForWrite(false);
1874 1995
1875 SetPartAsNonRoot(newPart); 1996 SetPartAsNonRoot(newPart);
1876 1997
@@ -1933,7 +2054,7 @@ namespace OpenSim.Region.Framework.Scenes
1933 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2054 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1934 // return; 2055 // return;
1935 2056
1936 lock (m_parts) 2057 lockPartsForRead(true);
1937 { 2058 {
1938 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2059 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1939 2060
@@ -1951,34 +2072,43 @@ namespace OpenSim.Region.Framework.Scenes
1951 2072
1952 foreach (SceneObjectPart part in m_parts.Values) 2073 foreach (SceneObjectPart part in m_parts.Values)
1953 { 2074 {
2075
1954 part.SendScheduledUpdates(); 2076 part.SendScheduledUpdates();
2077
1955 } 2078 }
1956 } 2079 }
2080 lockPartsForRead(false);
1957 } 2081 }
1958 2082
1959 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2083 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1960 { 2084 {
1961 RootPart.AddFullUpdateToAvatar(presence); 2085 RootPart.AddFullUpdateToAvatar(presence);
1962 2086
1963 lock (m_parts) 2087 lockPartsForRead(true);
1964 { 2088 {
1965 foreach (SceneObjectPart part in m_parts.Values) 2089 foreach (SceneObjectPart part in m_parts.Values)
1966 { 2090 {
2091
1967 if (part != RootPart) 2092 if (part != RootPart)
1968 part.AddFullUpdateToAvatar(presence); 2093 part.AddFullUpdateToAvatar(presence);
2094
1969 } 2095 }
1970 } 2096 }
2097 lockPartsForRead(false);
1971 } 2098 }
1972 2099
1973 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2100 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1974 { 2101 {
1975 lock (m_parts) 2102 lockPartsForRead(true);
1976 { 2103 {
1977 foreach (SceneObjectPart part in m_parts.Values) 2104 foreach (SceneObjectPart part in m_parts.Values)
1978 { 2105 {
2106
1979 part.AddTerseUpdateToAvatar(presence); 2107 part.AddTerseUpdateToAvatar(presence);
2108
1980 } 2109 }
1981 } 2110 }
2111 lockPartsForRead(false);
1982 } 2112 }
1983 2113
1984 /// <summary> 2114 /// <summary>
@@ -1989,14 +2119,17 @@ namespace OpenSim.Region.Framework.Scenes
1989 checkAtTargets(); 2119 checkAtTargets();
1990 RootPart.ScheduleFullUpdate(); 2120 RootPart.ScheduleFullUpdate();
1991 2121
1992 lock (m_parts) 2122 lockPartsForRead(true);
1993 { 2123 {
1994 foreach (SceneObjectPart part in m_parts.Values) 2124 foreach (SceneObjectPart part in m_parts.Values)
1995 { 2125 {
2126
1996 if (part != RootPart) 2127 if (part != RootPart)
1997 part.ScheduleFullUpdate(); 2128 part.ScheduleFullUpdate();
2129
1998 } 2130 }
1999 } 2131 }
2132 lockPartsForRead(false);
2000 } 2133 }
2001 2134
2002 /// <summary> 2135 /// <summary>
@@ -2004,13 +2137,16 @@ namespace OpenSim.Region.Framework.Scenes
2004 /// </summary> 2137 /// </summary>
2005 public void ScheduleGroupForTerseUpdate() 2138 public void ScheduleGroupForTerseUpdate()
2006 { 2139 {
2007 lock (m_parts) 2140 lockPartsForRead(true);
2008 { 2141 {
2009 foreach (SceneObjectPart part in m_parts.Values) 2142 foreach (SceneObjectPart part in m_parts.Values)
2010 { 2143 {
2144
2011 part.ScheduleTerseUpdate(); 2145 part.ScheduleTerseUpdate();
2146
2012 } 2147 }
2013 } 2148 }
2149 lockPartsForRead(false);
2014 } 2150 }
2015 2151
2016 /// <summary> 2152 /// <summary>
@@ -2023,14 +2159,17 @@ namespace OpenSim.Region.Framework.Scenes
2023 2159
2024 RootPart.SendFullUpdateToAllClients(); 2160 RootPart.SendFullUpdateToAllClients();
2025 2161
2026 lock (m_parts) 2162 lockPartsForRead(true);
2027 { 2163 {
2028 foreach (SceneObjectPart part in m_parts.Values) 2164 foreach (SceneObjectPart part in m_parts.Values)
2029 { 2165 {
2166
2030 if (part != RootPart) 2167 if (part != RootPart)
2031 part.SendFullUpdateToAllClients(); 2168 part.SendFullUpdateToAllClients();
2169
2032 } 2170 }
2033 } 2171 }
2172 lockPartsForRead(false);
2034 } 2173 }
2035 2174
2036 /// <summary> 2175 /// <summary>
@@ -2061,14 +2200,15 @@ namespace OpenSim.Region.Framework.Scenes
2061 { 2200 {
2062 if (IsDeleted) 2201 if (IsDeleted)
2063 return; 2202 return;
2064 2203
2065 lock (m_parts) 2204 lockPartsForRead(true);
2066 { 2205 {
2067 foreach (SceneObjectPart part in m_parts.Values) 2206 foreach (SceneObjectPart part in m_parts.Values)
2068 { 2207 {
2069 part.SendTerseUpdateToAllClients(); 2208 part.SendTerseUpdateToAllClients();
2070 } 2209 }
2071 } 2210 }
2211 lockPartsForRead(false);
2072 } 2212 }
2073 2213
2074 #endregion 2214 #endregion
@@ -2082,16 +2222,18 @@ namespace OpenSim.Region.Framework.Scenes
2082 /// <returns>null if no child part with that linknum or child part</returns> 2222 /// <returns>null if no child part with that linknum or child part</returns>
2083 public SceneObjectPart GetLinkNumPart(int linknum) 2223 public SceneObjectPart GetLinkNumPart(int linknum)
2084 { 2224 {
2085 lock (m_parts) 2225 lockPartsForRead(true);
2086 { 2226 {
2087 foreach (SceneObjectPart part in m_parts.Values) 2227 foreach (SceneObjectPart part in m_parts.Values)
2088 { 2228 {
2089 if (part.LinkNum == linknum) 2229 if (part.LinkNum == linknum)
2090 { 2230 {
2231 lockPartsForRead(false);
2091 return part; 2232 return part;
2092 } 2233 }
2093 } 2234 }
2094 } 2235 }
2236 lockPartsForRead(false);
2095 2237
2096 return null; 2238 return null;
2097 } 2239 }
@@ -2119,17 +2261,19 @@ namespace OpenSim.Region.Framework.Scenes
2119 public SceneObjectPart GetChildPart(uint localID) 2261 public SceneObjectPart GetChildPart(uint localID)
2120 { 2262 {
2121 //m_log.DebugFormat("Entered looking for {0}", localID); 2263 //m_log.DebugFormat("Entered looking for {0}", localID);
2122 lock (m_parts) 2264 lockPartsForRead(true);
2123 { 2265 {
2124 foreach (SceneObjectPart part in m_parts.Values) 2266 foreach (SceneObjectPart part in m_parts.Values)
2125 { 2267 {
2126 //m_log.DebugFormat("Found {0}", part.LocalId); 2268 //m_log.DebugFormat("Found {0}", part.LocalId);
2127 if (part.LocalId == localID) 2269 if (part.LocalId == localID)
2128 { 2270 {
2271 lockPartsForRead(false);
2129 return part; 2272 return part;
2130 } 2273 }
2131 } 2274 }
2132 } 2275 }
2276 lockPartsForRead(false);
2133 2277
2134 return null; 2278 return null;
2135 } 2279 }
@@ -2159,17 +2303,19 @@ namespace OpenSim.Region.Framework.Scenes
2159 public bool HasChildPrim(uint localID) 2303 public bool HasChildPrim(uint localID)
2160 { 2304 {
2161 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2305 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2162 lock (m_parts) 2306 lockPartsForRead(true);
2163 { 2307 {
2164 foreach (SceneObjectPart part in m_parts.Values) 2308 foreach (SceneObjectPart part in m_parts.Values)
2165 { 2309 {
2166 //m_log.DebugFormat("Found {0}", part.LocalId); 2310 //m_log.DebugFormat("Found {0}", part.LocalId);
2167 if (part.LocalId == localID) 2311 if (part.LocalId == localID)
2168 { 2312 {
2313 lockPartsForRead(false);
2169 return true; 2314 return true;
2170 } 2315 }
2171 } 2316 }
2172 } 2317 }
2318 lockPartsForRead(false);
2173 2319
2174 return false; 2320 return false;
2175 } 2321 }
@@ -2219,53 +2365,57 @@ namespace OpenSim.Region.Framework.Scenes
2219 if (m_rootPart.LinkNum == 0) 2365 if (m_rootPart.LinkNum == 0)
2220 m_rootPart.LinkNum = 1; 2366 m_rootPart.LinkNum = 1;
2221 2367
2222 lock (m_parts) 2368 lockPartsForWrite(true);
2223 { 2369
2224 m_parts.Add(linkPart.UUID, linkPart); 2370 m_parts.Add(linkPart.UUID, linkPart);
2225 2371
2226 // Insert in terms of link numbers, the new links 2372 lockPartsForWrite(false);
2227 // before the current ones (with the exception of 2373
2228 // the root prim. Shuffle the old ones up 2374 // Insert in terms of link numbers, the new links
2229 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2375 // before the current ones (with the exception of
2376 // the root prim. Shuffle the old ones up
2377 lockPartsForRead(true);
2378 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2379 {
2380 if (kvp.Value.LinkNum != 1)
2230 { 2381 {
2231 if (kvp.Value.LinkNum != 1) 2382 // Don't update root prim link number
2232 { 2383 kvp.Value.LinkNum += objectGroup.PrimCount;
2233 // Don't update root prim link number
2234 kvp.Value.LinkNum += objectGroup.PrimCount;
2235 }
2236 } 2384 }
2385 }
2386 lockPartsForRead(false);
2237 2387
2238 linkPart.LinkNum = 2; 2388 linkPart.LinkNum = 2;
2239 2389
2240 linkPart.SetParent(this); 2390 linkPart.SetParent(this);
2241 linkPart.AddFlag(PrimFlags.CreateSelected); 2391 linkPart.AddFlag(PrimFlags.CreateSelected);
2242 2392
2243 //if (linkPart.PhysActor != null) 2393 //if (linkPart.PhysActor != null)
2244 //{ 2394 //{
2245 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2395 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2246 2396
2247 //linkPart.PhysActor = null; 2397 //linkPart.PhysActor = null;
2248 //} 2398 //}
2249 2399
2250 //TODO: rest of parts 2400 //TODO: rest of parts
2251 int linkNum = 3; 2401 int linkNum = 3;
2252 foreach (SceneObjectPart part in objectGroup.Children.Values) 2402 foreach (SceneObjectPart part in objectGroup.Children.Values)
2403 {
2404 if (part.UUID != objectGroup.m_rootPart.UUID)
2253 { 2405 {
2254 if (part.UUID != objectGroup.m_rootPart.UUID) 2406 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2255 {
2256 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2257 }
2258 part.ClearUndoState();
2259 } 2407 }
2408 part.ClearUndoState();
2260 } 2409 }
2261 2410
2262 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2411 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2263 objectGroup.m_isDeleted = true; 2412 objectGroup.m_isDeleted = true;
2413
2414 objectGroup.lockPartsForWrite(true);
2264 2415
2265 lock (objectGroup.m_parts) 2416 objectGroup.m_parts.Clear();
2266 { 2417
2267 objectGroup.m_parts.Clear(); 2418 objectGroup.lockPartsForWrite(false);
2268 }
2269 2419
2270 // Can't do this yet since backup still makes use of the root part without any synchronization 2420 // Can't do this yet since backup still makes use of the root part without any synchronization
2271// objectGroup.m_rootPart = null; 2421// objectGroup.m_rootPart = null;
@@ -2324,11 +2474,12 @@ namespace OpenSim.Region.Framework.Scenes
2324 Quaternion worldRot = linkPart.GetWorldRotation(); 2474 Quaternion worldRot = linkPart.GetWorldRotation();
2325 2475
2326 // Remove the part from this object 2476 // Remove the part from this object
2327 lock (m_parts) 2477 lockPartsForWrite(true);
2328 { 2478 {
2329 m_parts.Remove(linkPart.UUID); 2479 m_parts.Remove(linkPart.UUID);
2330 } 2480 }
2331 2481 lockPartsForWrite(false);
2482 lockPartsForRead(true);
2332 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2483 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2333 RootPart.LinkNum = 0; 2484 RootPart.LinkNum = 0;
2334 else 2485 else
@@ -2339,6 +2490,7 @@ namespace OpenSim.Region.Framework.Scenes
2339 p.LinkNum--; 2490 p.LinkNum--;
2340 } 2491 }
2341 } 2492 }
2493 lockPartsForRead(false);
2342 2494
2343 linkPart.ParentID = 0; 2495 linkPart.ParentID = 0;
2344 linkPart.LinkNum = 0; 2496 linkPart.LinkNum = 0;
@@ -2656,9 +2808,12 @@ namespace OpenSim.Region.Framework.Scenes
2656 2808
2657 if (selectionPart != null) 2809 if (selectionPart != null)
2658 { 2810 {
2659 lock (m_parts) 2811 lockPartsForRead(true);
2812 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2813 lockPartsForRead(false);
2814 foreach (SceneObjectPart part in parts)
2660 { 2815 {
2661 foreach (SceneObjectPart part in m_parts.Values) 2816 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2662 { 2817 {
2663 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2818 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2664 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2819 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2668,12 +2823,13 @@ namespace OpenSim.Region.Framework.Scenes
2668 break; 2823 break;
2669 } 2824 }
2670 } 2825 }
2826 }
2671 2827
2672 foreach (SceneObjectPart part in m_parts.Values) 2828 foreach (SceneObjectPart part in parts)
2673 { 2829 {
2674 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2830 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2675 }
2676 } 2831 }
2832
2677 } 2833 }
2678 } 2834 }
2679 2835
@@ -2759,11 +2915,9 @@ namespace OpenSim.Region.Framework.Scenes
2759 scale.Y = m_scene.m_maxNonphys; 2915 scale.Y = m_scene.m_maxNonphys;
2760 if (scale.Z > m_scene.m_maxNonphys) 2916 if (scale.Z > m_scene.m_maxNonphys)
2761 scale.Z = m_scene.m_maxNonphys; 2917 scale.Z = m_scene.m_maxNonphys;
2762
2763 SceneObjectPart part = GetChildPart(localID); 2918 SceneObjectPart part = GetChildPart(localID);
2764 if (part != null) 2919 if (part != null)
2765 { 2920 {
2766 part.Resize(scale);
2767 if (part.PhysActor != null) 2921 if (part.PhysActor != null)
2768 { 2922 {
2769 if (part.PhysActor.IsPhysical) 2923 if (part.PhysActor.IsPhysical)
@@ -2778,7 +2932,7 @@ namespace OpenSim.Region.Framework.Scenes
2778 part.PhysActor.Size = scale; 2932 part.PhysActor.Size = scale;
2779 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2933 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2780 } 2934 }
2781 //if (part.UUID != m_rootPart.UUID) 2935 part.Resize(scale);
2782 2936
2783 HasGroupChanged = true; 2937 HasGroupChanged = true;
2784 ScheduleGroupForFullUpdate(); 2938 ScheduleGroupForFullUpdate();
@@ -2819,77 +2973,76 @@ namespace OpenSim.Region.Framework.Scenes
2819 float y = (scale.Y / part.Scale.Y); 2973 float y = (scale.Y / part.Scale.Y);
2820 float z = (scale.Z / part.Scale.Z); 2974 float z = (scale.Z / part.Scale.Z);
2821 2975
2822 lock (m_parts) 2976 lockPartsForRead(true);
2977 if (x > 1.0f || y > 1.0f || z > 1.0f)
2823 { 2978 {
2824 if (x > 1.0f || y > 1.0f || z > 1.0f) 2979 foreach (SceneObjectPart obPart in m_parts.Values)
2825 { 2980 {
2826 foreach (SceneObjectPart obPart in m_parts.Values) 2981 if (obPart.UUID != m_rootPart.UUID)
2827 { 2982 {
2828 if (obPart.UUID != m_rootPart.UUID) 2983 Vector3 oldSize = new Vector3(obPart.Scale);
2829 {
2830 Vector3 oldSize = new Vector3(obPart.Scale);
2831 2984
2832 float f = 1.0f; 2985 float f = 1.0f;
2833 float a = 1.0f; 2986 float a = 1.0f;
2834 2987
2835 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2988 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2989 {
2990 if (oldSize.X*x > m_scene.m_maxPhys)
2836 { 2991 {
2837 if (oldSize.X*x > m_scene.m_maxPhys) 2992 f = m_scene.m_maxPhys / oldSize.X;
2838 { 2993 a = f / x;
2839 f = m_scene.m_maxPhys / oldSize.X; 2994 x *= a;
2840 a = f / x; 2995 y *= a;
2841 x *= a; 2996 z *= a;
2842 y *= a;
2843 z *= a;
2844 }
2845 if (oldSize.Y*y > m_scene.m_maxPhys)
2846 {
2847 f = m_scene.m_maxPhys / oldSize.Y;
2848 a = f / y;
2849 x *= a;
2850 y *= a;
2851 z *= a;
2852 }
2853 if (oldSize.Z*z > m_scene.m_maxPhys)
2854 {
2855 f = m_scene.m_maxPhys / oldSize.Z;
2856 a = f / z;
2857 x *= a;
2858 y *= a;
2859 z *= a;
2860 }
2861 } 2997 }
2862 else 2998 if (oldSize.Y*y > m_scene.m_maxPhys)
2999 {
3000 f = m_scene.m_maxPhys / oldSize.Y;
3001 a = f / y;
3002 x *= a;
3003 y *= a;
3004 z *= a;
3005 }
3006 if (oldSize.Z*z > m_scene.m_maxPhys)
3007 {
3008 f = m_scene.m_maxPhys / oldSize.Z;
3009 a = f / z;
3010 x *= a;
3011 y *= a;
3012 z *= a;
3013 }
3014 }
3015 else
3016 {
3017 if (oldSize.X*x > m_scene.m_maxNonphys)
3018 {
3019 f = m_scene.m_maxNonphys / oldSize.X;
3020 a = f / x;
3021 x *= a;
3022 y *= a;
3023 z *= a;
3024 }
3025 if (oldSize.Y*y > m_scene.m_maxNonphys)
2863 { 3026 {
2864 if (oldSize.X*x > m_scene.m_maxNonphys) 3027 f = m_scene.m_maxNonphys / oldSize.Y;
2865 { 3028 a = f / y;
2866 f = m_scene.m_maxNonphys / oldSize.X; 3029 x *= a;
2867 a = f / x; 3030 y *= a;
2868 x *= a; 3031 z *= a;
2869 y *= a; 3032 }
2870 z *= a; 3033 if (oldSize.Z*z > m_scene.m_maxNonphys)
2871 } 3034 {
2872 if (oldSize.Y*y > m_scene.m_maxNonphys) 3035 f = m_scene.m_maxNonphys / oldSize.Z;
2873 { 3036 a = f / z;
2874 f = m_scene.m_maxNonphys / oldSize.Y; 3037 x *= a;
2875 a = f / y; 3038 y *= a;
2876 x *= a; 3039 z *= a;
2877 y *= a;
2878 z *= a;
2879 }
2880 if (oldSize.Z*z > m_scene.m_maxNonphys)
2881 {
2882 f = m_scene.m_maxNonphys / oldSize.Z;
2883 a = f / z;
2884 x *= a;
2885 y *= a;
2886 z *= a;
2887 }
2888 } 3040 }
2889 } 3041 }
2890 } 3042 }
2891 } 3043 }
2892 } 3044 }
3045 lockPartsForRead(false);
2893 3046
2894 Vector3 prevScale = part.Scale; 3047 Vector3 prevScale = part.Scale;
2895 prevScale.X *= x; 3048 prevScale.X *= x;
@@ -2897,7 +3050,7 @@ namespace OpenSim.Region.Framework.Scenes
2897 prevScale.Z *= z; 3050 prevScale.Z *= z;
2898 part.Resize(prevScale); 3051 part.Resize(prevScale);
2899 3052
2900 lock (m_parts) 3053 lockPartsForRead(true);
2901 { 3054 {
2902 foreach (SceneObjectPart obPart in m_parts.Values) 3055 foreach (SceneObjectPart obPart in m_parts.Values)
2903 { 3056 {
@@ -2916,6 +3069,7 @@ namespace OpenSim.Region.Framework.Scenes
2916 } 3069 }
2917 } 3070 }
2918 } 3071 }
3072 lockPartsForRead(false);
2919 3073
2920 if (part.PhysActor != null) 3074 if (part.PhysActor != null)
2921 { 3075 {
@@ -2996,7 +3150,7 @@ namespace OpenSim.Region.Framework.Scenes
2996 axDiff *= Quaternion.Inverse(partRotation); 3150 axDiff *= Quaternion.Inverse(partRotation);
2997 diff = axDiff; 3151 diff = axDiff;
2998 3152
2999 lock (m_parts) 3153 lockPartsForRead(true);
3000 { 3154 {
3001 foreach (SceneObjectPart obPart in m_parts.Values) 3155 foreach (SceneObjectPart obPart in m_parts.Values)
3002 { 3156 {
@@ -3006,6 +3160,7 @@ namespace OpenSim.Region.Framework.Scenes
3006 } 3160 }
3007 } 3161 }
3008 } 3162 }
3163 lockPartsForRead(false);
3009 3164
3010 AbsolutePosition = newPos; 3165 AbsolutePosition = newPos;
3011 3166
@@ -3123,7 +3278,7 @@ namespace OpenSim.Region.Framework.Scenes
3123 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3278 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3124 } 3279 }
3125 3280
3126 lock (m_parts) 3281 lockPartsForRead(true);
3127 { 3282 {
3128 foreach (SceneObjectPart prim in m_parts.Values) 3283 foreach (SceneObjectPart prim in m_parts.Values)
3129 { 3284 {
@@ -3141,6 +3296,7 @@ namespace OpenSim.Region.Framework.Scenes
3141 } 3296 }
3142 } 3297 }
3143 } 3298 }
3299 lockPartsForRead(false);
3144 3300
3145 m_rootPart.ScheduleTerseUpdate(); 3301 m_rootPart.ScheduleTerseUpdate();
3146 } 3302 }
@@ -3263,7 +3419,7 @@ namespace OpenSim.Region.Framework.Scenes
3263 if (atTargets.Count > 0) 3419 if (atTargets.Count > 0)
3264 { 3420 {
3265 uint[] localids = new uint[0]; 3421 uint[] localids = new uint[0];
3266 lock (m_parts) 3422 lockPartsForRead(true);
3267 { 3423 {
3268 localids = new uint[m_parts.Count]; 3424 localids = new uint[m_parts.Count];
3269 int cntr = 0; 3425 int cntr = 0;
@@ -3273,6 +3429,7 @@ namespace OpenSim.Region.Framework.Scenes
3273 cntr++; 3429 cntr++;
3274 } 3430 }
3275 } 3431 }
3432 lockPartsForRead(false);
3276 3433
3277 for (int ctr = 0; ctr < localids.Length; ctr++) 3434 for (int ctr = 0; ctr < localids.Length; ctr++)
3278 { 3435 {
@@ -3291,7 +3448,7 @@ namespace OpenSim.Region.Framework.Scenes
3291 { 3448 {
3292 //trigger not_at_target 3449 //trigger not_at_target
3293 uint[] localids = new uint[0]; 3450 uint[] localids = new uint[0];
3294 lock (m_parts) 3451 lockPartsForRead(true);
3295 { 3452 {
3296 localids = new uint[m_parts.Count]; 3453 localids = new uint[m_parts.Count];
3297 int cntr = 0; 3454 int cntr = 0;
@@ -3301,7 +3458,8 @@ namespace OpenSim.Region.Framework.Scenes
3301 cntr++; 3458 cntr++;
3302 } 3459 }
3303 } 3460 }
3304 3461 lockPartsForRead(false);
3462
3305 for (int ctr = 0; ctr < localids.Length; ctr++) 3463 for (int ctr = 0; ctr < localids.Length; ctr++)
3306 { 3464 {
3307 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3465 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3393,19 +3551,20 @@ namespace OpenSim.Region.Framework.Scenes
3393 public float GetMass() 3551 public float GetMass()
3394 { 3552 {
3395 float retmass = 0f; 3553 float retmass = 0f;
3396 lock (m_parts) 3554 lockPartsForRead(true);
3397 { 3555 {
3398 foreach (SceneObjectPart part in m_parts.Values) 3556 foreach (SceneObjectPart part in m_parts.Values)
3399 { 3557 {
3400 retmass += part.GetMass(); 3558 retmass += part.GetMass();
3401 } 3559 }
3402 } 3560 }
3561 lockPartsForRead(false);
3403 return retmass; 3562 return retmass;
3404 } 3563 }
3405 3564
3406 public void CheckSculptAndLoad() 3565 public void CheckSculptAndLoad()
3407 { 3566 {
3408 lock (m_parts) 3567 lockPartsForRead(true);
3409 { 3568 {
3410 if (!IsDeleted) 3569 if (!IsDeleted)
3411 { 3570 {
@@ -3430,6 +3589,7 @@ namespace OpenSim.Region.Framework.Scenes
3430 } 3589 }
3431 } 3590 }
3432 } 3591 }
3592 lockPartsForRead(false);
3433 } 3593 }
3434 3594
3435 protected void AssetReceived(string id, Object sender, AssetBase asset) 3595 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3450,7 +3610,7 @@ namespace OpenSim.Region.Framework.Scenes
3450 /// <param name="client"></param> 3610 /// <param name="client"></param>
3451 public void SetGroup(UUID GroupID, IClientAPI client) 3611 public void SetGroup(UUID GroupID, IClientAPI client)
3452 { 3612 {
3453 lock (m_parts) 3613 lockPartsForRead(true);
3454 { 3614 {
3455 foreach (SceneObjectPart part in m_parts.Values) 3615 foreach (SceneObjectPart part in m_parts.Values)
3456 { 3616 {
@@ -3460,7 +3620,7 @@ namespace OpenSim.Region.Framework.Scenes
3460 3620
3461 HasGroupChanged = true; 3621 HasGroupChanged = true;
3462 } 3622 }
3463 3623 lockPartsForRead(false);
3464 ScheduleGroupForFullUpdate(); 3624 ScheduleGroupForFullUpdate();
3465 } 3625 }
3466 3626
@@ -3479,11 +3639,12 @@ namespace OpenSim.Region.Framework.Scenes
3479 3639
3480 public void SetAttachmentPoint(byte point) 3640 public void SetAttachmentPoint(byte point)
3481 { 3641 {
3482 lock (m_parts) 3642 lockPartsForRead(true);
3483 { 3643 {
3484 foreach (SceneObjectPart part in m_parts.Values) 3644 foreach (SceneObjectPart part in m_parts.Values)
3485 part.SetAttachmentPoint(point); 3645 part.SetAttachmentPoint(point);
3486 } 3646 }
3647 lockPartsForRead(false);
3487 } 3648 }
3488 3649
3489 #region ISceneObject 3650 #region ISceneObject