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 af46659..4676a30 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
@@ -299,13 +368,16 @@ namespace OpenSim.Region.Framework.Scenes
299 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 368 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
300 } 369 }
301 370
302 lock (m_parts) 371 lockPartsForRead(true);
303 { 372 {
304 foreach (SceneObjectPart part in m_parts.Values) 373 foreach (SceneObjectPart part in m_parts.Values)
305 { 374 {
375
306 part.GroupPosition = val; 376 part.GroupPosition = val;
377
307 } 378 }
308 } 379 }
380 lockPartsForRead(false);
309 381
310 //if (m_rootPart.PhysActor != null) 382 //if (m_rootPart.PhysActor != null)
311 //{ 383 //{
@@ -467,13 +539,16 @@ namespace OpenSim.Region.Framework.Scenes
467 539
468 public void SetFromItemID(UUID AssetId) 540 public void SetFromItemID(UUID AssetId)
469 { 541 {
470 lock (m_parts) 542 lockPartsForRead(true);
471 { 543 {
472 foreach (SceneObjectPart part in m_parts.Values) 544 foreach (SceneObjectPart part in m_parts.Values)
473 { 545 {
546
474 part.FromItemID = AssetId; 547 part.FromItemID = AssetId;
548
475 } 549 }
476 } 550 }
551 lockPartsForRead(false);
477 } 552 }
478 553
479 public UUID GetFromItemID() 554 public UUID GetFromItemID()
@@ -540,10 +615,11 @@ namespace OpenSim.Region.Framework.Scenes
540 Vector3 maxScale = Vector3.Zero; 615 Vector3 maxScale = Vector3.Zero;
541 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 616 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
542 617
543 lock (m_parts) 618 lockPartsForRead(true);
544 { 619 {
545 foreach (SceneObjectPart part in m_parts.Values) 620 foreach (SceneObjectPart part in m_parts.Values)
546 { 621 {
622
547 Vector3 partscale = part.Scale; 623 Vector3 partscale = part.Scale;
548 Vector3 partoffset = part.OffsetPosition; 624 Vector3 partoffset = part.OffsetPosition;
549 625
@@ -554,8 +630,11 @@ namespace OpenSim.Region.Framework.Scenes
554 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 630 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
555 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 631 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
556 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 632 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
633
557 } 634 }
558 } 635 }
636 lockPartsForRead(false);
637
559 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 638 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
560 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 639 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
561 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 640 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -571,10 +650,11 @@ namespace OpenSim.Region.Framework.Scenes
571 650
572 EntityIntersection result = new EntityIntersection(); 651 EntityIntersection result = new EntityIntersection();
573 652
574 lock (m_parts) 653 lockPartsForRead(true);
575 { 654 {
576 foreach (SceneObjectPart part in m_parts.Values) 655 foreach (SceneObjectPart part in m_parts.Values)
577 { 656 {
657
578 // Temporary commented to stop compiler warning 658 // Temporary commented to stop compiler warning
579 //Vector3 partPosition = 659 //Vector3 partPosition =
580 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 660 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -602,8 +682,10 @@ namespace OpenSim.Region.Framework.Scenes
602 result.distance = inter.distance; 682 result.distance = inter.distance;
603 } 683 }
604 } 684 }
685
605 } 686 }
606 } 687 }
688 lockPartsForRead(false);
607 return result; 689 return result;
608 } 690 }
609 691
@@ -616,10 +698,11 @@ namespace OpenSim.Region.Framework.Scenes
616 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 698 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
617 { 699 {
618 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 700 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
619 lock (m_parts) 701 lockPartsForRead(true);
620 { 702 {
621 foreach (SceneObjectPart part in m_parts.Values) 703 foreach (SceneObjectPart part in m_parts.Values)
622 { 704 {
705
623 Vector3 worldPos = part.GetWorldPosition(); 706 Vector3 worldPos = part.GetWorldPosition();
624 Vector3 offset = worldPos - AbsolutePosition; 707 Vector3 offset = worldPos - AbsolutePosition;
625 Quaternion worldRot; 708 Quaternion worldRot;
@@ -678,6 +761,8 @@ namespace OpenSim.Region.Framework.Scenes
678 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 761 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
679 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 762 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
680 763
764
765
681 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 766 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
682 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 767 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
683 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 768 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -849,6 +934,7 @@ namespace OpenSim.Region.Framework.Scenes
849 minZ = backBottomLeft.Z; 934 minZ = backBottomLeft.Z;
850 } 935 }
851 } 936 }
937 lockPartsForRead(false);
852 938
853 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 939 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
854 940
@@ -877,17 +963,20 @@ namespace OpenSim.Region.Framework.Scenes
877 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 963 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
878 964
879 // Capture script state while holding the lock 965 // Capture script state while holding the lock
880 lock (m_parts) 966 lockPartsForRead(true);
881 { 967 {
882 foreach (SceneObjectPart part in m_parts.Values) 968 foreach (SceneObjectPart part in m_parts.Values)
883 { 969 {
970
884 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 971 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
885 foreach (UUID itemid in pstates.Keys) 972 foreach (UUID itemid in pstates.Keys)
886 { 973 {
887 states.Add(itemid, pstates[itemid]); 974 states.Add(itemid, pstates[itemid]);
888 } 975 }
976
889 } 977 }
890 } 978 }
979 lockPartsForRead(false);
891 980
892 if (states.Count > 0) 981 if (states.Count > 0)
893 { 982 {
@@ -1049,13 +1138,16 @@ namespace OpenSim.Region.Framework.Scenes
1049 1138
1050 public override void UpdateMovement() 1139 public override void UpdateMovement()
1051 { 1140 {
1052 lock (m_parts) 1141 lockPartsForRead(true);
1053 { 1142 {
1054 foreach (SceneObjectPart part in m_parts.Values) 1143 foreach (SceneObjectPart part in m_parts.Values)
1055 { 1144 {
1145
1056 part.UpdateMovement(); 1146 part.UpdateMovement();
1147
1057 } 1148 }
1058 } 1149 }
1150 lockPartsForRead(false);
1059 } 1151 }
1060 1152
1061 public ushort GetTimeDilation() 1153 public ushort GetTimeDilation()
@@ -1099,7 +1191,7 @@ namespace OpenSim.Region.Framework.Scenes
1099 /// <param name="part"></param> 1191 /// <param name="part"></param>
1100 public void AddPart(SceneObjectPart part) 1192 public void AddPart(SceneObjectPart part)
1101 { 1193 {
1102 lock (m_parts) 1194 lockPartsForWrite(true);
1103 { 1195 {
1104 part.SetParent(this); 1196 part.SetParent(this);
1105 m_parts.Add(part.UUID, part); 1197 m_parts.Add(part.UUID, part);
@@ -1109,6 +1201,7 @@ namespace OpenSim.Region.Framework.Scenes
1109 if (part.LinkNum == 2 && RootPart != null) 1201 if (part.LinkNum == 2 && RootPart != null)
1110 RootPart.LinkNum = 1; 1202 RootPart.LinkNum = 1;
1111 } 1203 }
1204 lockPartsForWrite(false);
1112 } 1205 }
1113 1206
1114 /// <summary> 1207 /// <summary>
@@ -1116,28 +1209,33 @@ namespace OpenSim.Region.Framework.Scenes
1116 /// </summary> 1209 /// </summary>
1117 private void UpdateParentIDs() 1210 private void UpdateParentIDs()
1118 { 1211 {
1119 lock (m_parts) 1212 lockPartsForRead(true);
1120 { 1213 {
1121 foreach (SceneObjectPart part in m_parts.Values) 1214 foreach (SceneObjectPart part in m_parts.Values)
1122 { 1215 {
1216
1123 if (part.UUID != m_rootPart.UUID) 1217 if (part.UUID != m_rootPart.UUID)
1124 { 1218 {
1125 part.ParentID = m_rootPart.LocalId; 1219 part.ParentID = m_rootPart.LocalId;
1126 } 1220 }
1221
1127 } 1222 }
1128 } 1223 }
1224 lockPartsForRead(false);
1129 } 1225 }
1130 1226
1131 public void RegenerateFullIDs() 1227 public void RegenerateFullIDs()
1132 { 1228 {
1133 lock (m_parts) 1229 lockPartsForRead(true);
1134 { 1230 {
1135 foreach (SceneObjectPart part in m_parts.Values) 1231 foreach (SceneObjectPart part in m_parts.Values)
1136 { 1232 {
1233
1137 part.UUID = UUID.Random(); 1234 part.UUID = UUID.Random();
1138 1235
1139 } 1236 }
1140 } 1237 }
1238 lockPartsForRead(false);
1141 } 1239 }
1142 1240
1143 // helper provided for parts. 1241 // helper provided for parts.
@@ -1218,29 +1316,33 @@ namespace OpenSim.Region.Framework.Scenes
1218 1316
1219 DetachFromBackup(); 1317 DetachFromBackup();
1220 1318
1221 lock (m_parts) 1319 lockPartsForRead(true);
1320 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1321 lockPartsForRead(false);
1322
1323 foreach (SceneObjectPart part in values)
1222 { 1324 {
1223 foreach (SceneObjectPart part in m_parts.Values)
1224 {
1225// part.Inventory.RemoveScriptInstances(); 1325// part.Inventory.RemoveScriptInstances();
1226 1326
1227 ScenePresence[] avatars = Scene.GetScenePresences(); 1327 ScenePresence[] avatars = Scene.GetScenePresences();
1228 for (int i = 0; i < avatars.Length; i++) 1328 for (int i = 0; i < avatars.Length; i++)
1329 {
1330 if (avatars[i].ParentID == LocalId)
1229 { 1331 {
1230 if (avatars[i].ParentID == LocalId) 1332 avatars[i].StandUp();
1231 { 1333 }
1232 avatars[i].StandUp();
1233 }
1234 1334
1235 if (!silent) 1335 if (!silent)
1236 { 1336 {
1237 part.UpdateFlag = 0; 1337 part.UpdateFlag = 0;
1238 if (part == m_rootPart) 1338 if (part == m_rootPart)
1239 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1339 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1240 }
1241 } 1340 }
1242 } 1341 }
1342
1243 } 1343 }
1344
1345
1244 } 1346 }
1245 1347
1246 public void AddScriptLPS(int count) 1348 public void AddScriptLPS(int count)
@@ -1265,17 +1367,20 @@ namespace OpenSim.Region.Framework.Scenes
1265 1367
1266 scriptEvents aggregateScriptEvents=0; 1368 scriptEvents aggregateScriptEvents=0;
1267 1369
1268 lock (m_parts) 1370 lockPartsForRead(true);
1269 { 1371 {
1270 foreach (SceneObjectPart part in m_parts.Values) 1372 foreach (SceneObjectPart part in m_parts.Values)
1271 { 1373 {
1374
1272 if (part == null) 1375 if (part == null)
1273 continue; 1376 continue;
1274 if (part != RootPart) 1377 if (part != RootPart)
1275 part.ObjectFlags = objectflagupdate; 1378 part.ObjectFlags = objectflagupdate;
1276 aggregateScriptEvents |= part.AggregateScriptEvents; 1379 aggregateScriptEvents |= part.AggregateScriptEvents;
1380
1277 } 1381 }
1278 } 1382 }
1383 lockPartsForRead(false);
1279 1384
1280 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1385 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1281 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1386 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1317,42 +1422,52 @@ namespace OpenSim.Region.Framework.Scenes
1317 /// <param name="m_physicalPrim"></param> 1422 /// <param name="m_physicalPrim"></param>
1318 public void ApplyPhysics(bool m_physicalPrim) 1423 public void ApplyPhysics(bool m_physicalPrim)
1319 { 1424 {
1320 lock (m_parts) 1425 lockPartsForRead(true);
1426
1427 if (m_parts.Count > 1)
1321 { 1428 {
1322 if (m_parts.Count > 1) 1429 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1430 lockPartsForRead(false);
1431 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1432 foreach (SceneObjectPart part in values)
1323 { 1433 {
1324 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1434
1325 foreach (SceneObjectPart part in m_parts.Values) 1435 if (part.LocalId != m_rootPart.LocalId)
1326 { 1436 {
1327 if (part.LocalId != m_rootPart.LocalId) 1437 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1328 {
1329 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1330 }
1331 } 1438 }
1332 1439
1333 // Hack to get the physics scene geometries in the right spot
1334 ResetChildPrimPhysicsPositions();
1335 }
1336 else
1337 {
1338 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1339 } 1440 }
1441 // Hack to get the physics scene geometries in the right spot
1442 ResetChildPrimPhysicsPositions();
1443 }
1444 else
1445 {
1446 lockPartsForRead(false);
1447 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1340 } 1448 }
1341 } 1449 }
1342 1450
1343 public void SetOwnerId(UUID userId) 1451 public void SetOwnerId(UUID userId)
1344 { 1452 {
1345 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1453 ForEachPart(delegate(SceneObjectPart part)
1454 {
1455
1456 part.OwnerID = userId;
1457
1458 });
1346 } 1459 }
1347 1460
1348 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1461 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1349 { 1462 {
1350 lock (m_parts) 1463 lockPartsForRead(true);
1464 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1465 lockPartsForRead(false);
1466 foreach (SceneObjectPart part in values)
1351 { 1467 {
1352 foreach (SceneObjectPart part in m_parts.Values) 1468
1353 { 1469 whatToDo(part);
1354 whatToDo(part); 1470
1355 }
1356 } 1471 }
1357 } 1472 }
1358 1473
@@ -1451,14 +1566,17 @@ namespace OpenSim.Region.Framework.Scenes
1451 { 1566 {
1452 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1567 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1453 1568
1454 lock (m_parts) 1569 lockPartsForRead(true);
1455 { 1570 {
1456 foreach (SceneObjectPart part in m_parts.Values) 1571 foreach (SceneObjectPart part in m_parts.Values)
1457 { 1572 {
1573
1458 if (part != RootPart) 1574 if (part != RootPart)
1459 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1575 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1576
1460 } 1577 }
1461 } 1578 }
1579 lockPartsForRead(false);
1462 } 1580 }
1463 1581
1464 /// <summary> 1582 /// <summary>
@@ -1553,10 +1671,11 @@ namespace OpenSim.Region.Framework.Scenes
1553 1671
1554 List<SceneObjectPart> partList; 1672 List<SceneObjectPart> partList;
1555 1673
1556 lock (m_parts) 1674 lockPartsForRead(true);
1557 { 1675
1558 partList = new List<SceneObjectPart>(m_parts.Values); 1676 partList = new List<SceneObjectPart>(m_parts.Values);
1559 } 1677
1678 lockPartsForRead(false);
1560 1679
1561 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1680 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1562 { 1681 {
@@ -1805,6 +1924,7 @@ namespace OpenSim.Region.Framework.Scenes
1805 } 1924 }
1806 } 1925 }
1807 } 1926 }
1927
1808 public void stopLookAt() 1928 public void stopLookAt()
1809 { 1929 {
1810 SceneObjectPart rootpart = m_rootPart; 1930 SceneObjectPart rootpart = m_rootPart;
@@ -1879,10 +1999,11 @@ namespace OpenSim.Region.Framework.Scenes
1879 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1999 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1880 newPart.SetParent(this); 2000 newPart.SetParent(this);
1881 2001
1882 lock (m_parts) 2002 lockPartsForWrite(true);
1883 { 2003 {
1884 m_parts.Add(newPart.UUID, newPart); 2004 m_parts.Add(newPart.UUID, newPart);
1885 } 2005 }
2006 lockPartsForWrite(false);
1886 2007
1887 SetPartAsNonRoot(newPart); 2008 SetPartAsNonRoot(newPart);
1888 2009
@@ -1945,7 +2066,7 @@ namespace OpenSim.Region.Framework.Scenes
1945 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2066 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1946 // return; 2067 // return;
1947 2068
1948 lock (m_parts) 2069 lockPartsForRead(true);
1949 { 2070 {
1950 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2071 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1951 2072
@@ -1963,34 +2084,43 @@ namespace OpenSim.Region.Framework.Scenes
1963 2084
1964 foreach (SceneObjectPart part in m_parts.Values) 2085 foreach (SceneObjectPart part in m_parts.Values)
1965 { 2086 {
2087
1966 part.SendScheduledUpdates(); 2088 part.SendScheduledUpdates();
2089
1967 } 2090 }
1968 } 2091 }
2092 lockPartsForRead(false);
1969 } 2093 }
1970 2094
1971 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2095 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1972 { 2096 {
1973 RootPart.AddFullUpdateToAvatar(presence); 2097 RootPart.AddFullUpdateToAvatar(presence);
1974 2098
1975 lock (m_parts) 2099 lockPartsForRead(true);
1976 { 2100 {
1977 foreach (SceneObjectPart part in m_parts.Values) 2101 foreach (SceneObjectPart part in m_parts.Values)
1978 { 2102 {
2103
1979 if (part != RootPart) 2104 if (part != RootPart)
1980 part.AddFullUpdateToAvatar(presence); 2105 part.AddFullUpdateToAvatar(presence);
2106
1981 } 2107 }
1982 } 2108 }
2109 lockPartsForRead(false);
1983 } 2110 }
1984 2111
1985 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2112 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1986 { 2113 {
1987 lock (m_parts) 2114 lockPartsForRead(true);
1988 { 2115 {
1989 foreach (SceneObjectPart part in m_parts.Values) 2116 foreach (SceneObjectPart part in m_parts.Values)
1990 { 2117 {
2118
1991 part.AddTerseUpdateToAvatar(presence); 2119 part.AddTerseUpdateToAvatar(presence);
2120
1992 } 2121 }
1993 } 2122 }
2123 lockPartsForRead(false);
1994 } 2124 }
1995 2125
1996 /// <summary> 2126 /// <summary>
@@ -2001,14 +2131,17 @@ namespace OpenSim.Region.Framework.Scenes
2001 checkAtTargets(); 2131 checkAtTargets();
2002 RootPart.ScheduleFullUpdate(); 2132 RootPart.ScheduleFullUpdate();
2003 2133
2004 lock (m_parts) 2134 lockPartsForRead(true);
2005 { 2135 {
2006 foreach (SceneObjectPart part in m_parts.Values) 2136 foreach (SceneObjectPart part in m_parts.Values)
2007 { 2137 {
2138
2008 if (part != RootPart) 2139 if (part != RootPart)
2009 part.ScheduleFullUpdate(); 2140 part.ScheduleFullUpdate();
2141
2010 } 2142 }
2011 } 2143 }
2144 lockPartsForRead(false);
2012 } 2145 }
2013 2146
2014 /// <summary> 2147 /// <summary>
@@ -2016,13 +2149,16 @@ namespace OpenSim.Region.Framework.Scenes
2016 /// </summary> 2149 /// </summary>
2017 public void ScheduleGroupForTerseUpdate() 2150 public void ScheduleGroupForTerseUpdate()
2018 { 2151 {
2019 lock (m_parts) 2152 lockPartsForRead(true);
2020 { 2153 {
2021 foreach (SceneObjectPart part in m_parts.Values) 2154 foreach (SceneObjectPart part in m_parts.Values)
2022 { 2155 {
2156
2023 part.ScheduleTerseUpdate(); 2157 part.ScheduleTerseUpdate();
2158
2024 } 2159 }
2025 } 2160 }
2161 lockPartsForRead(false);
2026 } 2162 }
2027 2163
2028 /// <summary> 2164 /// <summary>
@@ -2035,14 +2171,17 @@ namespace OpenSim.Region.Framework.Scenes
2035 2171
2036 RootPart.SendFullUpdateToAllClients(); 2172 RootPart.SendFullUpdateToAllClients();
2037 2173
2038 lock (m_parts) 2174 lockPartsForRead(true);
2039 { 2175 {
2040 foreach (SceneObjectPart part in m_parts.Values) 2176 foreach (SceneObjectPart part in m_parts.Values)
2041 { 2177 {
2178
2042 if (part != RootPart) 2179 if (part != RootPart)
2043 part.SendFullUpdateToAllClients(); 2180 part.SendFullUpdateToAllClients();
2181
2044 } 2182 }
2045 } 2183 }
2184 lockPartsForRead(false);
2046 } 2185 }
2047 2186
2048 /// <summary> 2187 /// <summary>
@@ -2073,14 +2212,15 @@ namespace OpenSim.Region.Framework.Scenes
2073 { 2212 {
2074 if (IsDeleted) 2213 if (IsDeleted)
2075 return; 2214 return;
2076 2215
2077 lock (m_parts) 2216 lockPartsForRead(true);
2078 { 2217 {
2079 foreach (SceneObjectPart part in m_parts.Values) 2218 foreach (SceneObjectPart part in m_parts.Values)
2080 { 2219 {
2081 part.SendTerseUpdateToAllClients(); 2220 part.SendTerseUpdateToAllClients();
2082 } 2221 }
2083 } 2222 }
2223 lockPartsForRead(false);
2084 } 2224 }
2085 2225
2086 #endregion 2226 #endregion
@@ -2094,16 +2234,18 @@ namespace OpenSim.Region.Framework.Scenes
2094 /// <returns>null if no child part with that linknum or child part</returns> 2234 /// <returns>null if no child part with that linknum or child part</returns>
2095 public SceneObjectPart GetLinkNumPart(int linknum) 2235 public SceneObjectPart GetLinkNumPart(int linknum)
2096 { 2236 {
2097 lock (m_parts) 2237 lockPartsForRead(true);
2098 { 2238 {
2099 foreach (SceneObjectPart part in m_parts.Values) 2239 foreach (SceneObjectPart part in m_parts.Values)
2100 { 2240 {
2101 if (part.LinkNum == linknum) 2241 if (part.LinkNum == linknum)
2102 { 2242 {
2243 lockPartsForRead(false);
2103 return part; 2244 return part;
2104 } 2245 }
2105 } 2246 }
2106 } 2247 }
2248 lockPartsForRead(false);
2107 2249
2108 return null; 2250 return null;
2109 } 2251 }
@@ -2131,17 +2273,19 @@ namespace OpenSim.Region.Framework.Scenes
2131 public SceneObjectPart GetChildPart(uint localID) 2273 public SceneObjectPart GetChildPart(uint localID)
2132 { 2274 {
2133 //m_log.DebugFormat("Entered looking for {0}", localID); 2275 //m_log.DebugFormat("Entered looking for {0}", localID);
2134 lock (m_parts) 2276 lockPartsForRead(true);
2135 { 2277 {
2136 foreach (SceneObjectPart part in m_parts.Values) 2278 foreach (SceneObjectPart part in m_parts.Values)
2137 { 2279 {
2138 //m_log.DebugFormat("Found {0}", part.LocalId); 2280 //m_log.DebugFormat("Found {0}", part.LocalId);
2139 if (part.LocalId == localID) 2281 if (part.LocalId == localID)
2140 { 2282 {
2283 lockPartsForRead(false);
2141 return part; 2284 return part;
2142 } 2285 }
2143 } 2286 }
2144 } 2287 }
2288 lockPartsForRead(false);
2145 2289
2146 return null; 2290 return null;
2147 } 2291 }
@@ -2171,17 +2315,19 @@ namespace OpenSim.Region.Framework.Scenes
2171 public bool HasChildPrim(uint localID) 2315 public bool HasChildPrim(uint localID)
2172 { 2316 {
2173 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2317 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2174 lock (m_parts) 2318 lockPartsForRead(true);
2175 { 2319 {
2176 foreach (SceneObjectPart part in m_parts.Values) 2320 foreach (SceneObjectPart part in m_parts.Values)
2177 { 2321 {
2178 //m_log.DebugFormat("Found {0}", part.LocalId); 2322 //m_log.DebugFormat("Found {0}", part.LocalId);
2179 if (part.LocalId == localID) 2323 if (part.LocalId == localID)
2180 { 2324 {
2325 lockPartsForRead(false);
2181 return true; 2326 return true;
2182 } 2327 }
2183 } 2328 }
2184 } 2329 }
2330 lockPartsForRead(false);
2185 2331
2186 return false; 2332 return false;
2187 } 2333 }
@@ -2231,53 +2377,57 @@ namespace OpenSim.Region.Framework.Scenes
2231 if (m_rootPart.LinkNum == 0) 2377 if (m_rootPart.LinkNum == 0)
2232 m_rootPart.LinkNum = 1; 2378 m_rootPart.LinkNum = 1;
2233 2379
2234 lock (m_parts) 2380 lockPartsForWrite(true);
2235 { 2381
2236 m_parts.Add(linkPart.UUID, linkPart); 2382 m_parts.Add(linkPart.UUID, linkPart);
2237 2383
2238 // Insert in terms of link numbers, the new links 2384 lockPartsForWrite(false);
2239 // before the current ones (with the exception of 2385
2240 // the root prim. Shuffle the old ones up 2386 // Insert in terms of link numbers, the new links
2241 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2387 // before the current ones (with the exception of
2388 // the root prim. Shuffle the old ones up
2389 lockPartsForRead(true);
2390 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2391 {
2392 if (kvp.Value.LinkNum != 1)
2242 { 2393 {
2243 if (kvp.Value.LinkNum != 1) 2394 // Don't update root prim link number
2244 { 2395 kvp.Value.LinkNum += objectGroup.PrimCount;
2245 // Don't update root prim link number
2246 kvp.Value.LinkNum += objectGroup.PrimCount;
2247 }
2248 } 2396 }
2397 }
2398 lockPartsForRead(false);
2249 2399
2250 linkPart.LinkNum = 2; 2400 linkPart.LinkNum = 2;
2251 2401
2252 linkPart.SetParent(this); 2402 linkPart.SetParent(this);
2253 linkPart.AddFlag(PrimFlags.CreateSelected); 2403 linkPart.AddFlag(PrimFlags.CreateSelected);
2254 2404
2255 //if (linkPart.PhysActor != null) 2405 //if (linkPart.PhysActor != null)
2256 //{ 2406 //{
2257 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2407 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2258 2408
2259 //linkPart.PhysActor = null; 2409 //linkPart.PhysActor = null;
2260 //} 2410 //}
2261 2411
2262 //TODO: rest of parts 2412 //TODO: rest of parts
2263 int linkNum = 3; 2413 int linkNum = 3;
2264 foreach (SceneObjectPart part in objectGroup.Children.Values) 2414 foreach (SceneObjectPart part in objectGroup.Children.Values)
2415 {
2416 if (part.UUID != objectGroup.m_rootPart.UUID)
2265 { 2417 {
2266 if (part.UUID != objectGroup.m_rootPart.UUID) 2418 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2267 {
2268 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2269 }
2270 part.ClearUndoState();
2271 } 2419 }
2420 part.ClearUndoState();
2272 } 2421 }
2273 2422
2274 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2423 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2275 objectGroup.m_isDeleted = true; 2424 objectGroup.m_isDeleted = true;
2425
2426 objectGroup.lockPartsForWrite(true);
2276 2427
2277 lock (objectGroup.m_parts) 2428 objectGroup.m_parts.Clear();
2278 { 2429
2279 objectGroup.m_parts.Clear(); 2430 objectGroup.lockPartsForWrite(false);
2280 }
2281 2431
2282 // Can't do this yet since backup still makes use of the root part without any synchronization 2432 // Can't do this yet since backup still makes use of the root part without any synchronization
2283// objectGroup.m_rootPart = null; 2433// objectGroup.m_rootPart = null;
@@ -2336,11 +2486,12 @@ namespace OpenSim.Region.Framework.Scenes
2336 Quaternion worldRot = linkPart.GetWorldRotation(); 2486 Quaternion worldRot = linkPart.GetWorldRotation();
2337 2487
2338 // Remove the part from this object 2488 // Remove the part from this object
2339 lock (m_parts) 2489 lockPartsForWrite(true);
2340 { 2490 {
2341 m_parts.Remove(linkPart.UUID); 2491 m_parts.Remove(linkPart.UUID);
2342 } 2492 }
2343 2493 lockPartsForWrite(false);
2494 lockPartsForRead(true);
2344 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2495 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2345 RootPart.LinkNum = 0; 2496 RootPart.LinkNum = 0;
2346 else 2497 else
@@ -2351,6 +2502,7 @@ namespace OpenSim.Region.Framework.Scenes
2351 p.LinkNum--; 2502 p.LinkNum--;
2352 } 2503 }
2353 } 2504 }
2505 lockPartsForRead(false);
2354 2506
2355 linkPart.ParentID = 0; 2507 linkPart.ParentID = 0;
2356 linkPart.LinkNum = 0; 2508 linkPart.LinkNum = 0;
@@ -2668,9 +2820,12 @@ namespace OpenSim.Region.Framework.Scenes
2668 2820
2669 if (selectionPart != null) 2821 if (selectionPart != null)
2670 { 2822 {
2671 lock (m_parts) 2823 lockPartsForRead(true);
2824 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2825 lockPartsForRead(false);
2826 foreach (SceneObjectPart part in parts)
2672 { 2827 {
2673 foreach (SceneObjectPart part in m_parts.Values) 2828 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2674 { 2829 {
2675 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2830 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2676 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2831 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2680,12 +2835,13 @@ namespace OpenSim.Region.Framework.Scenes
2680 break; 2835 break;
2681 } 2836 }
2682 } 2837 }
2838 }
2683 2839
2684 foreach (SceneObjectPart part in m_parts.Values) 2840 foreach (SceneObjectPart part in parts)
2685 { 2841 {
2686 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2842 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2687 }
2688 } 2843 }
2844
2689 } 2845 }
2690 } 2846 }
2691 2847
@@ -2771,11 +2927,9 @@ namespace OpenSim.Region.Framework.Scenes
2771 scale.Y = m_scene.m_maxNonphys; 2927 scale.Y = m_scene.m_maxNonphys;
2772 if (scale.Z > m_scene.m_maxNonphys) 2928 if (scale.Z > m_scene.m_maxNonphys)
2773 scale.Z = m_scene.m_maxNonphys; 2929 scale.Z = m_scene.m_maxNonphys;
2774
2775 SceneObjectPart part = GetChildPart(localID); 2930 SceneObjectPart part = GetChildPart(localID);
2776 if (part != null) 2931 if (part != null)
2777 { 2932 {
2778 part.Resize(scale);
2779 if (part.PhysActor != null) 2933 if (part.PhysActor != null)
2780 { 2934 {
2781 if (part.PhysActor.IsPhysical) 2935 if (part.PhysActor.IsPhysical)
@@ -2790,7 +2944,7 @@ namespace OpenSim.Region.Framework.Scenes
2790 part.PhysActor.Size = scale; 2944 part.PhysActor.Size = scale;
2791 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2945 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2792 } 2946 }
2793 //if (part.UUID != m_rootPart.UUID) 2947 part.Resize(scale);
2794 2948
2795 HasGroupChanged = true; 2949 HasGroupChanged = true;
2796 ScheduleGroupForFullUpdate(); 2950 ScheduleGroupForFullUpdate();
@@ -2831,77 +2985,76 @@ namespace OpenSim.Region.Framework.Scenes
2831 float y = (scale.Y / part.Scale.Y); 2985 float y = (scale.Y / part.Scale.Y);
2832 float z = (scale.Z / part.Scale.Z); 2986 float z = (scale.Z / part.Scale.Z);
2833 2987
2834 lock (m_parts) 2988 lockPartsForRead(true);
2989 if (x > 1.0f || y > 1.0f || z > 1.0f)
2835 { 2990 {
2836 if (x > 1.0f || y > 1.0f || z > 1.0f) 2991 foreach (SceneObjectPart obPart in m_parts.Values)
2837 { 2992 {
2838 foreach (SceneObjectPart obPart in m_parts.Values) 2993 if (obPart.UUID != m_rootPart.UUID)
2839 { 2994 {
2840 if (obPart.UUID != m_rootPart.UUID) 2995 Vector3 oldSize = new Vector3(obPart.Scale);
2841 {
2842 Vector3 oldSize = new Vector3(obPart.Scale);
2843 2996
2844 float f = 1.0f; 2997 float f = 1.0f;
2845 float a = 1.0f; 2998 float a = 1.0f;
2846 2999
2847 if (part.PhysActor != null && part.PhysActor.IsPhysical) 3000 if (part.PhysActor != null && part.PhysActor.IsPhysical)
3001 {
3002 if (oldSize.X*x > m_scene.m_maxPhys)
2848 { 3003 {
2849 if (oldSize.X*x > m_scene.m_maxPhys) 3004 f = m_scene.m_maxPhys / oldSize.X;
2850 { 3005 a = f / x;
2851 f = m_scene.m_maxPhys / oldSize.X; 3006 x *= a;
2852 a = f / x; 3007 y *= a;
2853 x *= a; 3008 z *= a;
2854 y *= a;
2855 z *= a;
2856 }
2857 if (oldSize.Y*y > m_scene.m_maxPhys)
2858 {
2859 f = m_scene.m_maxPhys / oldSize.Y;
2860 a = f / y;
2861 x *= a;
2862 y *= a;
2863 z *= a;
2864 }
2865 if (oldSize.Z*z > m_scene.m_maxPhys)
2866 {
2867 f = m_scene.m_maxPhys / oldSize.Z;
2868 a = f / z;
2869 x *= a;
2870 y *= a;
2871 z *= a;
2872 }
2873 } 3009 }
2874 else 3010 if (oldSize.Y*y > m_scene.m_maxPhys)
3011 {
3012 f = m_scene.m_maxPhys / oldSize.Y;
3013 a = f / y;
3014 x *= a;
3015 y *= a;
3016 z *= a;
3017 }
3018 if (oldSize.Z*z > m_scene.m_maxPhys)
3019 {
3020 f = m_scene.m_maxPhys / oldSize.Z;
3021 a = f / z;
3022 x *= a;
3023 y *= a;
3024 z *= a;
3025 }
3026 }
3027 else
3028 {
3029 if (oldSize.X*x > m_scene.m_maxNonphys)
3030 {
3031 f = m_scene.m_maxNonphys / oldSize.X;
3032 a = f / x;
3033 x *= a;
3034 y *= a;
3035 z *= a;
3036 }
3037 if (oldSize.Y*y > m_scene.m_maxNonphys)
3038 {
3039 f = m_scene.m_maxNonphys / oldSize.Y;
3040 a = f / y;
3041 x *= a;
3042 y *= a;
3043 z *= a;
3044 }
3045 if (oldSize.Z*z > m_scene.m_maxNonphys)
2875 { 3046 {
2876 if (oldSize.X*x > m_scene.m_maxNonphys) 3047 f = m_scene.m_maxNonphys / oldSize.Z;
2877 { 3048 a = f / z;
2878 f = m_scene.m_maxNonphys / oldSize.X; 3049 x *= a;
2879 a = f / x; 3050 y *= a;
2880 x *= a; 3051 z *= a;
2881 y *= a;
2882 z *= a;
2883 }
2884 if (oldSize.Y*y > m_scene.m_maxNonphys)
2885 {
2886 f = m_scene.m_maxNonphys / oldSize.Y;
2887 a = f / y;
2888 x *= a;
2889 y *= a;
2890 z *= a;
2891 }
2892 if (oldSize.Z*z > m_scene.m_maxNonphys)
2893 {
2894 f = m_scene.m_maxNonphys / oldSize.Z;
2895 a = f / z;
2896 x *= a;
2897 y *= a;
2898 z *= a;
2899 }
2900 } 3052 }
2901 } 3053 }
2902 } 3054 }
2903 } 3055 }
2904 } 3056 }
3057 lockPartsForRead(false);
2905 3058
2906 Vector3 prevScale = part.Scale; 3059 Vector3 prevScale = part.Scale;
2907 prevScale.X *= x; 3060 prevScale.X *= x;
@@ -2909,7 +3062,7 @@ namespace OpenSim.Region.Framework.Scenes
2909 prevScale.Z *= z; 3062 prevScale.Z *= z;
2910 part.Resize(prevScale); 3063 part.Resize(prevScale);
2911 3064
2912 lock (m_parts) 3065 lockPartsForRead(true);
2913 { 3066 {
2914 foreach (SceneObjectPart obPart in m_parts.Values) 3067 foreach (SceneObjectPart obPart in m_parts.Values)
2915 { 3068 {
@@ -2928,6 +3081,7 @@ namespace OpenSim.Region.Framework.Scenes
2928 } 3081 }
2929 } 3082 }
2930 } 3083 }
3084 lockPartsForRead(false);
2931 3085
2932 if (part.PhysActor != null) 3086 if (part.PhysActor != null)
2933 { 3087 {
@@ -3008,7 +3162,7 @@ namespace OpenSim.Region.Framework.Scenes
3008 axDiff *= Quaternion.Inverse(partRotation); 3162 axDiff *= Quaternion.Inverse(partRotation);
3009 diff = axDiff; 3163 diff = axDiff;
3010 3164
3011 lock (m_parts) 3165 lockPartsForRead(true);
3012 { 3166 {
3013 foreach (SceneObjectPart obPart in m_parts.Values) 3167 foreach (SceneObjectPart obPart in m_parts.Values)
3014 { 3168 {
@@ -3018,6 +3172,7 @@ namespace OpenSim.Region.Framework.Scenes
3018 } 3172 }
3019 } 3173 }
3020 } 3174 }
3175 lockPartsForRead(false);
3021 3176
3022 AbsolutePosition = newPos; 3177 AbsolutePosition = newPos;
3023 3178
@@ -3135,7 +3290,7 @@ namespace OpenSim.Region.Framework.Scenes
3135 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3290 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3136 } 3291 }
3137 3292
3138 lock (m_parts) 3293 lockPartsForRead(true);
3139 { 3294 {
3140 foreach (SceneObjectPart prim in m_parts.Values) 3295 foreach (SceneObjectPart prim in m_parts.Values)
3141 { 3296 {
@@ -3153,6 +3308,7 @@ namespace OpenSim.Region.Framework.Scenes
3153 } 3308 }
3154 } 3309 }
3155 } 3310 }
3311 lockPartsForRead(false);
3156 3312
3157 m_rootPart.ScheduleTerseUpdate(); 3313 m_rootPart.ScheduleTerseUpdate();
3158 } 3314 }
@@ -3275,7 +3431,7 @@ namespace OpenSim.Region.Framework.Scenes
3275 if (atTargets.Count > 0) 3431 if (atTargets.Count > 0)
3276 { 3432 {
3277 uint[] localids = new uint[0]; 3433 uint[] localids = new uint[0];
3278 lock (m_parts) 3434 lockPartsForRead(true);
3279 { 3435 {
3280 localids = new uint[m_parts.Count]; 3436 localids = new uint[m_parts.Count];
3281 int cntr = 0; 3437 int cntr = 0;
@@ -3285,6 +3441,7 @@ namespace OpenSim.Region.Framework.Scenes
3285 cntr++; 3441 cntr++;
3286 } 3442 }
3287 } 3443 }
3444 lockPartsForRead(false);
3288 3445
3289 for (int ctr = 0; ctr < localids.Length; ctr++) 3446 for (int ctr = 0; ctr < localids.Length; ctr++)
3290 { 3447 {
@@ -3303,7 +3460,7 @@ namespace OpenSim.Region.Framework.Scenes
3303 { 3460 {
3304 //trigger not_at_target 3461 //trigger not_at_target
3305 uint[] localids = new uint[0]; 3462 uint[] localids = new uint[0];
3306 lock (m_parts) 3463 lockPartsForRead(true);
3307 { 3464 {
3308 localids = new uint[m_parts.Count]; 3465 localids = new uint[m_parts.Count];
3309 int cntr = 0; 3466 int cntr = 0;
@@ -3313,7 +3470,8 @@ namespace OpenSim.Region.Framework.Scenes
3313 cntr++; 3470 cntr++;
3314 } 3471 }
3315 } 3472 }
3316 3473 lockPartsForRead(false);
3474
3317 for (int ctr = 0; ctr < localids.Length; ctr++) 3475 for (int ctr = 0; ctr < localids.Length; ctr++)
3318 { 3476 {
3319 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3477 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3405,19 +3563,20 @@ namespace OpenSim.Region.Framework.Scenes
3405 public float GetMass() 3563 public float GetMass()
3406 { 3564 {
3407 float retmass = 0f; 3565 float retmass = 0f;
3408 lock (m_parts) 3566 lockPartsForRead(true);
3409 { 3567 {
3410 foreach (SceneObjectPart part in m_parts.Values) 3568 foreach (SceneObjectPart part in m_parts.Values)
3411 { 3569 {
3412 retmass += part.GetMass(); 3570 retmass += part.GetMass();
3413 } 3571 }
3414 } 3572 }
3573 lockPartsForRead(false);
3415 return retmass; 3574 return retmass;
3416 } 3575 }
3417 3576
3418 public void CheckSculptAndLoad() 3577 public void CheckSculptAndLoad()
3419 { 3578 {
3420 lock (m_parts) 3579 lockPartsForRead(true);
3421 { 3580 {
3422 if (!IsDeleted) 3581 if (!IsDeleted)
3423 { 3582 {
@@ -3442,6 +3601,7 @@ namespace OpenSim.Region.Framework.Scenes
3442 } 3601 }
3443 } 3602 }
3444 } 3603 }
3604 lockPartsForRead(false);
3445 } 3605 }
3446 3606
3447 protected void AssetReceived(string id, Object sender, AssetBase asset) 3607 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3462,7 +3622,7 @@ namespace OpenSim.Region.Framework.Scenes
3462 /// <param name="client"></param> 3622 /// <param name="client"></param>
3463 public void SetGroup(UUID GroupID, IClientAPI client) 3623 public void SetGroup(UUID GroupID, IClientAPI client)
3464 { 3624 {
3465 lock (m_parts) 3625 lockPartsForRead(true);
3466 { 3626 {
3467 foreach (SceneObjectPart part in m_parts.Values) 3627 foreach (SceneObjectPart part in m_parts.Values)
3468 { 3628 {
@@ -3472,7 +3632,7 @@ namespace OpenSim.Region.Framework.Scenes
3472 3632
3473 HasGroupChanged = true; 3633 HasGroupChanged = true;
3474 } 3634 }
3475 3635 lockPartsForRead(false);
3476 ScheduleGroupForFullUpdate(); 3636 ScheduleGroupForFullUpdate();
3477 } 3637 }
3478 3638
@@ -3491,11 +3651,12 @@ namespace OpenSim.Region.Framework.Scenes
3491 3651
3492 public void SetAttachmentPoint(byte point) 3652 public void SetAttachmentPoint(byte point)
3493 { 3653 {
3494 lock (m_parts) 3654 lockPartsForRead(true);
3495 { 3655 {
3496 foreach (SceneObjectPart part in m_parts.Values) 3656 foreach (SceneObjectPart part in m_parts.Values)
3497 part.SetAttachmentPoint(point); 3657 part.SetAttachmentPoint(point);
3498 } 3658 }
3659 lockPartsForRead(false);
3499 } 3660 }
3500 3661
3501 #region ISceneObject 3662 #region ISceneObject