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 e9ed066..f8498c6 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 //{
@@ -432,13 +504,16 @@ namespace OpenSim.Region.Framework.Scenes
432 504
433 public void SetFromItemID(UUID AssetId) 505 public void SetFromItemID(UUID AssetId)
434 { 506 {
435 lock (m_parts) 507 lockPartsForRead(true);
436 { 508 {
437 foreach (SceneObjectPart part in m_parts.Values) 509 foreach (SceneObjectPart part in m_parts.Values)
438 { 510 {
511
439 part.FromItemID = AssetId; 512 part.FromItemID = AssetId;
513
440 } 514 }
441 } 515 }
516 lockPartsForRead(false);
442 } 517 }
443 518
444 public UUID GetFromItemID() 519 public UUID GetFromItemID()
@@ -505,10 +580,11 @@ namespace OpenSim.Region.Framework.Scenes
505 Vector3 maxScale = Vector3.Zero; 580 Vector3 maxScale = Vector3.Zero;
506 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 581 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
507 582
508 lock (m_parts) 583 lockPartsForRead(true);
509 { 584 {
510 foreach (SceneObjectPart part in m_parts.Values) 585 foreach (SceneObjectPart part in m_parts.Values)
511 { 586 {
587
512 Vector3 partscale = part.Scale; 588 Vector3 partscale = part.Scale;
513 Vector3 partoffset = part.OffsetPosition; 589 Vector3 partoffset = part.OffsetPosition;
514 590
@@ -519,8 +595,11 @@ namespace OpenSim.Region.Framework.Scenes
519 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 595 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
520 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 596 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
521 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 597 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
598
522 } 599 }
523 } 600 }
601 lockPartsForRead(false);
602
524 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 603 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
525 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 604 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
526 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 605 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -536,10 +615,11 @@ namespace OpenSim.Region.Framework.Scenes
536 615
537 EntityIntersection result = new EntityIntersection(); 616 EntityIntersection result = new EntityIntersection();
538 617
539 lock (m_parts) 618 lockPartsForRead(true);
540 { 619 {
541 foreach (SceneObjectPart part in m_parts.Values) 620 foreach (SceneObjectPart part in m_parts.Values)
542 { 621 {
622
543 // Temporary commented to stop compiler warning 623 // Temporary commented to stop compiler warning
544 //Vector3 partPosition = 624 //Vector3 partPosition =
545 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 625 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -567,8 +647,10 @@ namespace OpenSim.Region.Framework.Scenes
567 result.distance = inter.distance; 647 result.distance = inter.distance;
568 } 648 }
569 } 649 }
650
570 } 651 }
571 } 652 }
653 lockPartsForRead(false);
572 return result; 654 return result;
573 } 655 }
574 656
@@ -581,10 +663,11 @@ namespace OpenSim.Region.Framework.Scenes
581 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 663 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
582 { 664 {
583 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 665 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
584 lock (m_parts) 666 lockPartsForRead(true);
585 { 667 {
586 foreach (SceneObjectPart part in m_parts.Values) 668 foreach (SceneObjectPart part in m_parts.Values)
587 { 669 {
670
588 Vector3 worldPos = part.GetWorldPosition(); 671 Vector3 worldPos = part.GetWorldPosition();
589 Vector3 offset = worldPos - AbsolutePosition; 672 Vector3 offset = worldPos - AbsolutePosition;
590 Quaternion worldRot; 673 Quaternion worldRot;
@@ -643,6 +726,8 @@ namespace OpenSim.Region.Framework.Scenes
643 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 726 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
644 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 727 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
645 728
729
730
646 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 731 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
647 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 732 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
648 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 733 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -814,6 +899,7 @@ namespace OpenSim.Region.Framework.Scenes
814 minZ = backBottomLeft.Z; 899 minZ = backBottomLeft.Z;
815 } 900 }
816 } 901 }
902 lockPartsForRead(false);
817 903
818 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 904 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
819 905
@@ -842,17 +928,20 @@ namespace OpenSim.Region.Framework.Scenes
842 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 928 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
843 929
844 // Capture script state while holding the lock 930 // Capture script state while holding the lock
845 lock (m_parts) 931 lockPartsForRead(true);
846 { 932 {
847 foreach (SceneObjectPart part in m_parts.Values) 933 foreach (SceneObjectPart part in m_parts.Values)
848 { 934 {
935
849 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 936 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
850 foreach (UUID itemid in pstates.Keys) 937 foreach (UUID itemid in pstates.Keys)
851 { 938 {
852 states.Add(itemid, pstates[itemid]); 939 states.Add(itemid, pstates[itemid]);
853 } 940 }
941
854 } 942 }
855 } 943 }
944 lockPartsForRead(false);
856 945
857 if (states.Count > 0) 946 if (states.Count > 0)
858 { 947 {
@@ -1014,13 +1103,16 @@ namespace OpenSim.Region.Framework.Scenes
1014 1103
1015 public override void UpdateMovement() 1104 public override void UpdateMovement()
1016 { 1105 {
1017 lock (m_parts) 1106 lockPartsForRead(true);
1018 { 1107 {
1019 foreach (SceneObjectPart part in m_parts.Values) 1108 foreach (SceneObjectPart part in m_parts.Values)
1020 { 1109 {
1110
1021 part.UpdateMovement(); 1111 part.UpdateMovement();
1112
1022 } 1113 }
1023 } 1114 }
1115 lockPartsForRead(false);
1024 } 1116 }
1025 1117
1026 public ushort GetTimeDilation() 1118 public ushort GetTimeDilation()
@@ -1064,7 +1156,7 @@ namespace OpenSim.Region.Framework.Scenes
1064 /// <param name="part"></param> 1156 /// <param name="part"></param>
1065 public void AddPart(SceneObjectPart part) 1157 public void AddPart(SceneObjectPart part)
1066 { 1158 {
1067 lock (m_parts) 1159 lockPartsForWrite(true);
1068 { 1160 {
1069 part.SetParent(this); 1161 part.SetParent(this);
1070 m_parts.Add(part.UUID, part); 1162 m_parts.Add(part.UUID, part);
@@ -1074,6 +1166,7 @@ namespace OpenSim.Region.Framework.Scenes
1074 if (part.LinkNum == 2 && RootPart != null) 1166 if (part.LinkNum == 2 && RootPart != null)
1075 RootPart.LinkNum = 1; 1167 RootPart.LinkNum = 1;
1076 } 1168 }
1169 lockPartsForWrite(false);
1077 } 1170 }
1078 1171
1079 /// <summary> 1172 /// <summary>
@@ -1081,28 +1174,33 @@ namespace OpenSim.Region.Framework.Scenes
1081 /// </summary> 1174 /// </summary>
1082 private void UpdateParentIDs() 1175 private void UpdateParentIDs()
1083 { 1176 {
1084 lock (m_parts) 1177 lockPartsForRead(true);
1085 { 1178 {
1086 foreach (SceneObjectPart part in m_parts.Values) 1179 foreach (SceneObjectPart part in m_parts.Values)
1087 { 1180 {
1181
1088 if (part.UUID != m_rootPart.UUID) 1182 if (part.UUID != m_rootPart.UUID)
1089 { 1183 {
1090 part.ParentID = m_rootPart.LocalId; 1184 part.ParentID = m_rootPart.LocalId;
1091 } 1185 }
1186
1092 } 1187 }
1093 } 1188 }
1189 lockPartsForRead(false);
1094 } 1190 }
1095 1191
1096 public void RegenerateFullIDs() 1192 public void RegenerateFullIDs()
1097 { 1193 {
1098 lock (m_parts) 1194 lockPartsForRead(true);
1099 { 1195 {
1100 foreach (SceneObjectPart part in m_parts.Values) 1196 foreach (SceneObjectPart part in m_parts.Values)
1101 { 1197 {
1198
1102 part.UUID = UUID.Random(); 1199 part.UUID = UUID.Random();
1103 1200
1104 } 1201 }
1105 } 1202 }
1203 lockPartsForRead(false);
1106 } 1204 }
1107 1205
1108 // helper provided for parts. 1206 // helper provided for parts.
@@ -1183,29 +1281,33 @@ namespace OpenSim.Region.Framework.Scenes
1183 1281
1184 DetachFromBackup(); 1282 DetachFromBackup();
1185 1283
1186 lock (m_parts) 1284 lockPartsForRead(true);
1285 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1286 lockPartsForRead(false);
1287
1288 foreach (SceneObjectPart part in values)
1187 { 1289 {
1188 foreach (SceneObjectPart part in m_parts.Values)
1189 {
1190// part.Inventory.RemoveScriptInstances(); 1290// part.Inventory.RemoveScriptInstances();
1191 1291
1192 ScenePresence[] avatars = Scene.GetScenePresences(); 1292 ScenePresence[] avatars = Scene.GetScenePresences();
1193 for (int i = 0; i < avatars.Length; i++) 1293 for (int i = 0; i < avatars.Length; i++)
1294 {
1295 if (avatars[i].ParentID == LocalId)
1194 { 1296 {
1195 if (avatars[i].ParentID == LocalId) 1297 avatars[i].StandUp();
1196 { 1298 }
1197 avatars[i].StandUp();
1198 }
1199 1299
1200 if (!silent) 1300 if (!silent)
1201 { 1301 {
1202 part.UpdateFlag = 0; 1302 part.UpdateFlag = 0;
1203 if (part == m_rootPart) 1303 if (part == m_rootPart)
1204 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1304 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1205 }
1206 } 1305 }
1207 } 1306 }
1307
1208 } 1308 }
1309
1310
1209 } 1311 }
1210 1312
1211 public void AddScriptLPS(int count) 1313 public void AddScriptLPS(int count)
@@ -1230,17 +1332,20 @@ namespace OpenSim.Region.Framework.Scenes
1230 1332
1231 scriptEvents aggregateScriptEvents=0; 1333 scriptEvents aggregateScriptEvents=0;
1232 1334
1233 lock (m_parts) 1335 lockPartsForRead(true);
1234 { 1336 {
1235 foreach (SceneObjectPart part in m_parts.Values) 1337 foreach (SceneObjectPart part in m_parts.Values)
1236 { 1338 {
1339
1237 if (part == null) 1340 if (part == null)
1238 continue; 1341 continue;
1239 if (part != RootPart) 1342 if (part != RootPart)
1240 part.ObjectFlags = objectflagupdate; 1343 part.ObjectFlags = objectflagupdate;
1241 aggregateScriptEvents |= part.AggregateScriptEvents; 1344 aggregateScriptEvents |= part.AggregateScriptEvents;
1345
1242 } 1346 }
1243 } 1347 }
1348 lockPartsForRead(false);
1244 1349
1245 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1350 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1246 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1351 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1273,42 +1378,52 @@ namespace OpenSim.Region.Framework.Scenes
1273 /// <param name="m_physicalPrim"></param> 1378 /// <param name="m_physicalPrim"></param>
1274 public void ApplyPhysics(bool m_physicalPrim) 1379 public void ApplyPhysics(bool m_physicalPrim)
1275 { 1380 {
1276 lock (m_parts) 1381 lockPartsForRead(true);
1382
1383 if (m_parts.Count > 1)
1277 { 1384 {
1278 if (m_parts.Count > 1) 1385 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1386 lockPartsForRead(false);
1387 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1388 foreach (SceneObjectPart part in values)
1279 { 1389 {
1280 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1390
1281 foreach (SceneObjectPart part in m_parts.Values) 1391 if (part.LocalId != m_rootPart.LocalId)
1282 { 1392 {
1283 if (part.LocalId != m_rootPart.LocalId) 1393 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1284 {
1285 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1286 }
1287 } 1394 }
1288 1395
1289 // Hack to get the physics scene geometries in the right spot
1290 ResetChildPrimPhysicsPositions();
1291 }
1292 else
1293 {
1294 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1295 } 1396 }
1397 // Hack to get the physics scene geometries in the right spot
1398 ResetChildPrimPhysicsPositions();
1399 }
1400 else
1401 {
1402 lockPartsForRead(false);
1403 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1296 } 1404 }
1297 } 1405 }
1298 1406
1299 public void SetOwnerId(UUID userId) 1407 public void SetOwnerId(UUID userId)
1300 { 1408 {
1301 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1409 ForEachPart(delegate(SceneObjectPart part)
1410 {
1411
1412 part.OwnerID = userId;
1413
1414 });
1302 } 1415 }
1303 1416
1304 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1417 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1305 { 1418 {
1306 lock (m_parts) 1419 lockPartsForRead(true);
1420 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1421 lockPartsForRead(false);
1422 foreach (SceneObjectPart part in values)
1307 { 1423 {
1308 foreach (SceneObjectPart part in m_parts.Values) 1424
1309 { 1425 whatToDo(part);
1310 whatToDo(part); 1426
1311 }
1312 } 1427 }
1313 } 1428 }
1314 1429
@@ -1407,14 +1522,17 @@ namespace OpenSim.Region.Framework.Scenes
1407 { 1522 {
1408 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1523 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1409 1524
1410 lock (m_parts) 1525 lockPartsForRead(true);
1411 { 1526 {
1412 foreach (SceneObjectPart part in m_parts.Values) 1527 foreach (SceneObjectPart part in m_parts.Values)
1413 { 1528 {
1529
1414 if (part != RootPart) 1530 if (part != RootPart)
1415 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1531 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1532
1416 } 1533 }
1417 } 1534 }
1535 lockPartsForRead(false);
1418 } 1536 }
1419 1537
1420 /// <summary> 1538 /// <summary>
@@ -1509,10 +1627,11 @@ namespace OpenSim.Region.Framework.Scenes
1509 1627
1510 List<SceneObjectPart> partList; 1628 List<SceneObjectPart> partList;
1511 1629
1512 lock (m_parts) 1630 lockPartsForRead(true);
1513 { 1631
1514 partList = new List<SceneObjectPart>(m_parts.Values); 1632 partList = new List<SceneObjectPart>(m_parts.Values);
1515 } 1633
1634 lockPartsForRead(false);
1516 1635
1517 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1636 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1518 { 1637 {
@@ -1761,6 +1880,7 @@ namespace OpenSim.Region.Framework.Scenes
1761 } 1880 }
1762 } 1881 }
1763 } 1882 }
1883
1764 public void stopLookAt() 1884 public void stopLookAt()
1765 { 1885 {
1766 SceneObjectPart rootpart = m_rootPart; 1886 SceneObjectPart rootpart = m_rootPart;
@@ -1835,10 +1955,11 @@ namespace OpenSim.Region.Framework.Scenes
1835 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1955 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1836 newPart.SetParent(this); 1956 newPart.SetParent(this);
1837 1957
1838 lock (m_parts) 1958 lockPartsForWrite(true);
1839 { 1959 {
1840 m_parts.Add(newPart.UUID, newPart); 1960 m_parts.Add(newPart.UUID, newPart);
1841 } 1961 }
1962 lockPartsForWrite(false);
1842 1963
1843 SetPartAsNonRoot(newPart); 1964 SetPartAsNonRoot(newPart);
1844 1965
@@ -1901,7 +2022,7 @@ namespace OpenSim.Region.Framework.Scenes
1901 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2022 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1902 // return; 2023 // return;
1903 2024
1904 lock (m_parts) 2025 lockPartsForRead(true);
1905 { 2026 {
1906 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2027 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1907 2028
@@ -1919,34 +2040,43 @@ namespace OpenSim.Region.Framework.Scenes
1919 2040
1920 foreach (SceneObjectPart part in m_parts.Values) 2041 foreach (SceneObjectPart part in m_parts.Values)
1921 { 2042 {
2043
1922 part.SendScheduledUpdates(); 2044 part.SendScheduledUpdates();
2045
1923 } 2046 }
1924 } 2047 }
2048 lockPartsForRead(false);
1925 } 2049 }
1926 2050
1927 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2051 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1928 { 2052 {
1929 RootPart.AddFullUpdateToAvatar(presence); 2053 RootPart.AddFullUpdateToAvatar(presence);
1930 2054
1931 lock (m_parts) 2055 lockPartsForRead(true);
1932 { 2056 {
1933 foreach (SceneObjectPart part in m_parts.Values) 2057 foreach (SceneObjectPart part in m_parts.Values)
1934 { 2058 {
2059
1935 if (part != RootPart) 2060 if (part != RootPart)
1936 part.AddFullUpdateToAvatar(presence); 2061 part.AddFullUpdateToAvatar(presence);
2062
1937 } 2063 }
1938 } 2064 }
2065 lockPartsForRead(false);
1939 } 2066 }
1940 2067
1941 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2068 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1942 { 2069 {
1943 lock (m_parts) 2070 lockPartsForRead(true);
1944 { 2071 {
1945 foreach (SceneObjectPart part in m_parts.Values) 2072 foreach (SceneObjectPart part in m_parts.Values)
1946 { 2073 {
2074
1947 part.AddTerseUpdateToAvatar(presence); 2075 part.AddTerseUpdateToAvatar(presence);
2076
1948 } 2077 }
1949 } 2078 }
2079 lockPartsForRead(false);
1950 } 2080 }
1951 2081
1952 /// <summary> 2082 /// <summary>
@@ -1957,14 +2087,17 @@ namespace OpenSim.Region.Framework.Scenes
1957 checkAtTargets(); 2087 checkAtTargets();
1958 RootPart.ScheduleFullUpdate(); 2088 RootPart.ScheduleFullUpdate();
1959 2089
1960 lock (m_parts) 2090 lockPartsForRead(true);
1961 { 2091 {
1962 foreach (SceneObjectPart part in m_parts.Values) 2092 foreach (SceneObjectPart part in m_parts.Values)
1963 { 2093 {
2094
1964 if (part != RootPart) 2095 if (part != RootPart)
1965 part.ScheduleFullUpdate(); 2096 part.ScheduleFullUpdate();
2097
1966 } 2098 }
1967 } 2099 }
2100 lockPartsForRead(false);
1968 } 2101 }
1969 2102
1970 /// <summary> 2103 /// <summary>
@@ -1972,13 +2105,16 @@ namespace OpenSim.Region.Framework.Scenes
1972 /// </summary> 2105 /// </summary>
1973 public void ScheduleGroupForTerseUpdate() 2106 public void ScheduleGroupForTerseUpdate()
1974 { 2107 {
1975 lock (m_parts) 2108 lockPartsForRead(true);
1976 { 2109 {
1977 foreach (SceneObjectPart part in m_parts.Values) 2110 foreach (SceneObjectPart part in m_parts.Values)
1978 { 2111 {
2112
1979 part.ScheduleTerseUpdate(); 2113 part.ScheduleTerseUpdate();
2114
1980 } 2115 }
1981 } 2116 }
2117 lockPartsForRead(false);
1982 } 2118 }
1983 2119
1984 /// <summary> 2120 /// <summary>
@@ -1991,14 +2127,17 @@ namespace OpenSim.Region.Framework.Scenes
1991 2127
1992 RootPart.SendFullUpdateToAllClients(); 2128 RootPart.SendFullUpdateToAllClients();
1993 2129
1994 lock (m_parts) 2130 lockPartsForRead(true);
1995 { 2131 {
1996 foreach (SceneObjectPart part in m_parts.Values) 2132 foreach (SceneObjectPart part in m_parts.Values)
1997 { 2133 {
2134
1998 if (part != RootPart) 2135 if (part != RootPart)
1999 part.SendFullUpdateToAllClients(); 2136 part.SendFullUpdateToAllClients();
2137
2000 } 2138 }
2001 } 2139 }
2140 lockPartsForRead(false);
2002 } 2141 }
2003 2142
2004 /// <summary> 2143 /// <summary>
@@ -2029,14 +2168,15 @@ namespace OpenSim.Region.Framework.Scenes
2029 { 2168 {
2030 if (IsDeleted) 2169 if (IsDeleted)
2031 return; 2170 return;
2032 2171
2033 lock (m_parts) 2172 lockPartsForRead(true);
2034 { 2173 {
2035 foreach (SceneObjectPart part in m_parts.Values) 2174 foreach (SceneObjectPart part in m_parts.Values)
2036 { 2175 {
2037 part.SendTerseUpdateToAllClients(); 2176 part.SendTerseUpdateToAllClients();
2038 } 2177 }
2039 } 2178 }
2179 lockPartsForRead(false);
2040 } 2180 }
2041 2181
2042 #endregion 2182 #endregion
@@ -2050,16 +2190,18 @@ namespace OpenSim.Region.Framework.Scenes
2050 /// <returns>null if no child part with that linknum or child part</returns> 2190 /// <returns>null if no child part with that linknum or child part</returns>
2051 public SceneObjectPart GetLinkNumPart(int linknum) 2191 public SceneObjectPart GetLinkNumPart(int linknum)
2052 { 2192 {
2053 lock (m_parts) 2193 lockPartsForRead(true);
2054 { 2194 {
2055 foreach (SceneObjectPart part in m_parts.Values) 2195 foreach (SceneObjectPart part in m_parts.Values)
2056 { 2196 {
2057 if (part.LinkNum == linknum) 2197 if (part.LinkNum == linknum)
2058 { 2198 {
2199 lockPartsForRead(false);
2059 return part; 2200 return part;
2060 } 2201 }
2061 } 2202 }
2062 } 2203 }
2204 lockPartsForRead(false);
2063 2205
2064 return null; 2206 return null;
2065 } 2207 }
@@ -2087,17 +2229,19 @@ namespace OpenSim.Region.Framework.Scenes
2087 public SceneObjectPart GetChildPart(uint localID) 2229 public SceneObjectPart GetChildPart(uint localID)
2088 { 2230 {
2089 //m_log.DebugFormat("Entered looking for {0}", localID); 2231 //m_log.DebugFormat("Entered looking for {0}", localID);
2090 lock (m_parts) 2232 lockPartsForRead(true);
2091 { 2233 {
2092 foreach (SceneObjectPart part in m_parts.Values) 2234 foreach (SceneObjectPart part in m_parts.Values)
2093 { 2235 {
2094 //m_log.DebugFormat("Found {0}", part.LocalId); 2236 //m_log.DebugFormat("Found {0}", part.LocalId);
2095 if (part.LocalId == localID) 2237 if (part.LocalId == localID)
2096 { 2238 {
2239 lockPartsForRead(false);
2097 return part; 2240 return part;
2098 } 2241 }
2099 } 2242 }
2100 } 2243 }
2244 lockPartsForRead(false);
2101 2245
2102 return null; 2246 return null;
2103 } 2247 }
@@ -2127,17 +2271,19 @@ namespace OpenSim.Region.Framework.Scenes
2127 public bool HasChildPrim(uint localID) 2271 public bool HasChildPrim(uint localID)
2128 { 2272 {
2129 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2273 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2130 lock (m_parts) 2274 lockPartsForRead(true);
2131 { 2275 {
2132 foreach (SceneObjectPart part in m_parts.Values) 2276 foreach (SceneObjectPart part in m_parts.Values)
2133 { 2277 {
2134 //m_log.DebugFormat("Found {0}", part.LocalId); 2278 //m_log.DebugFormat("Found {0}", part.LocalId);
2135 if (part.LocalId == localID) 2279 if (part.LocalId == localID)
2136 { 2280 {
2281 lockPartsForRead(false);
2137 return true; 2282 return true;
2138 } 2283 }
2139 } 2284 }
2140 } 2285 }
2286 lockPartsForRead(false);
2141 2287
2142 return false; 2288 return false;
2143 } 2289 }
@@ -2187,53 +2333,57 @@ namespace OpenSim.Region.Framework.Scenes
2187 if (m_rootPart.LinkNum == 0) 2333 if (m_rootPart.LinkNum == 0)
2188 m_rootPart.LinkNum = 1; 2334 m_rootPart.LinkNum = 1;
2189 2335
2190 lock (m_parts) 2336 lockPartsForWrite(true);
2191 { 2337
2192 m_parts.Add(linkPart.UUID, linkPart); 2338 m_parts.Add(linkPart.UUID, linkPart);
2193 2339
2194 // Insert in terms of link numbers, the new links 2340 lockPartsForWrite(false);
2195 // before the current ones (with the exception of 2341
2196 // the root prim. Shuffle the old ones up 2342 // Insert in terms of link numbers, the new links
2197 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2343 // before the current ones (with the exception of
2344 // the root prim. Shuffle the old ones up
2345 lockPartsForRead(true);
2346 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2347 {
2348 if (kvp.Value.LinkNum != 1)
2198 { 2349 {
2199 if (kvp.Value.LinkNum != 1) 2350 // Don't update root prim link number
2200 { 2351 kvp.Value.LinkNum += objectGroup.PrimCount;
2201 // Don't update root prim link number
2202 kvp.Value.LinkNum += objectGroup.PrimCount;
2203 }
2204 } 2352 }
2353 }
2354 lockPartsForRead(false);
2205 2355
2206 linkPart.LinkNum = 2; 2356 linkPart.LinkNum = 2;
2207 2357
2208 linkPart.SetParent(this); 2358 linkPart.SetParent(this);
2209 linkPart.AddFlag(PrimFlags.CreateSelected); 2359 linkPart.AddFlag(PrimFlags.CreateSelected);
2210 2360
2211 //if (linkPart.PhysActor != null) 2361 //if (linkPart.PhysActor != null)
2212 //{ 2362 //{
2213 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2363 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2214 2364
2215 //linkPart.PhysActor = null; 2365 //linkPart.PhysActor = null;
2216 //} 2366 //}
2217 2367
2218 //TODO: rest of parts 2368 //TODO: rest of parts
2219 int linkNum = 3; 2369 int linkNum = 3;
2220 foreach (SceneObjectPart part in objectGroup.Children.Values) 2370 foreach (SceneObjectPart part in objectGroup.Children.Values)
2371 {
2372 if (part.UUID != objectGroup.m_rootPart.UUID)
2221 { 2373 {
2222 if (part.UUID != objectGroup.m_rootPart.UUID) 2374 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2223 {
2224 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2225 }
2226 part.ClearUndoState();
2227 } 2375 }
2376 part.ClearUndoState();
2228 } 2377 }
2229 2378
2230 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2379 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2231 objectGroup.m_isDeleted = true; 2380 objectGroup.m_isDeleted = true;
2381
2382 objectGroup.lockPartsForWrite(true);
2232 2383
2233 lock (objectGroup.m_parts) 2384 objectGroup.m_parts.Clear();
2234 { 2385
2235 objectGroup.m_parts.Clear(); 2386 objectGroup.lockPartsForWrite(false);
2236 }
2237 2387
2238 // Can't do this yet since backup still makes use of the root part without any synchronization 2388 // Can't do this yet since backup still makes use of the root part without any synchronization
2239// objectGroup.m_rootPart = null; 2389// objectGroup.m_rootPart = null;
@@ -2292,11 +2442,12 @@ namespace OpenSim.Region.Framework.Scenes
2292 Quaternion worldRot = linkPart.GetWorldRotation(); 2442 Quaternion worldRot = linkPart.GetWorldRotation();
2293 2443
2294 // Remove the part from this object 2444 // Remove the part from this object
2295 lock (m_parts) 2445 lockPartsForWrite(true);
2296 { 2446 {
2297 m_parts.Remove(linkPart.UUID); 2447 m_parts.Remove(linkPart.UUID);
2298 } 2448 }
2299 2449 lockPartsForWrite(false);
2450 lockPartsForRead(true);
2300 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2451 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2301 RootPart.LinkNum = 0; 2452 RootPart.LinkNum = 0;
2302 else 2453 else
@@ -2307,6 +2458,7 @@ namespace OpenSim.Region.Framework.Scenes
2307 p.LinkNum--; 2458 p.LinkNum--;
2308 } 2459 }
2309 } 2460 }
2461 lockPartsForRead(false);
2310 2462
2311 linkPart.ParentID = 0; 2463 linkPart.ParentID = 0;
2312 linkPart.LinkNum = 0; 2464 linkPart.LinkNum = 0;
@@ -2624,9 +2776,12 @@ namespace OpenSim.Region.Framework.Scenes
2624 2776
2625 if (selectionPart != null) 2777 if (selectionPart != null)
2626 { 2778 {
2627 lock (m_parts) 2779 lockPartsForRead(true);
2780 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2781 lockPartsForRead(false);
2782 foreach (SceneObjectPart part in parts)
2628 { 2783 {
2629 foreach (SceneObjectPart part in m_parts.Values) 2784 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2630 { 2785 {
2631 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2786 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2632 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2787 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2636,12 +2791,13 @@ namespace OpenSim.Region.Framework.Scenes
2636 break; 2791 break;
2637 } 2792 }
2638 } 2793 }
2794 }
2639 2795
2640 foreach (SceneObjectPart part in m_parts.Values) 2796 foreach (SceneObjectPart part in parts)
2641 { 2797 {
2642 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2798 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2643 }
2644 } 2799 }
2800
2645 } 2801 }
2646 } 2802 }
2647 2803
@@ -2727,11 +2883,9 @@ namespace OpenSim.Region.Framework.Scenes
2727 scale.Y = m_scene.m_maxNonphys; 2883 scale.Y = m_scene.m_maxNonphys;
2728 if (scale.Z > m_scene.m_maxNonphys) 2884 if (scale.Z > m_scene.m_maxNonphys)
2729 scale.Z = m_scene.m_maxNonphys; 2885 scale.Z = m_scene.m_maxNonphys;
2730
2731 SceneObjectPart part = GetChildPart(localID); 2886 SceneObjectPart part = GetChildPart(localID);
2732 if (part != null) 2887 if (part != null)
2733 { 2888 {
2734 part.Resize(scale);
2735 if (part.PhysActor != null) 2889 if (part.PhysActor != null)
2736 { 2890 {
2737 if (part.PhysActor.IsPhysical) 2891 if (part.PhysActor.IsPhysical)
@@ -2746,7 +2900,7 @@ namespace OpenSim.Region.Framework.Scenes
2746 part.PhysActor.Size = scale; 2900 part.PhysActor.Size = scale;
2747 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2901 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2748 } 2902 }
2749 //if (part.UUID != m_rootPart.UUID) 2903 part.Resize(scale);
2750 2904
2751 HasGroupChanged = true; 2905 HasGroupChanged = true;
2752 ScheduleGroupForFullUpdate(); 2906 ScheduleGroupForFullUpdate();
@@ -2787,77 +2941,76 @@ namespace OpenSim.Region.Framework.Scenes
2787 float y = (scale.Y / part.Scale.Y); 2941 float y = (scale.Y / part.Scale.Y);
2788 float z = (scale.Z / part.Scale.Z); 2942 float z = (scale.Z / part.Scale.Z);
2789 2943
2790 lock (m_parts) 2944 lockPartsForRead(true);
2945 if (x > 1.0f || y > 1.0f || z > 1.0f)
2791 { 2946 {
2792 if (x > 1.0f || y > 1.0f || z > 1.0f) 2947 foreach (SceneObjectPart obPart in m_parts.Values)
2793 { 2948 {
2794 foreach (SceneObjectPart obPart in m_parts.Values) 2949 if (obPart.UUID != m_rootPart.UUID)
2795 { 2950 {
2796 if (obPart.UUID != m_rootPart.UUID) 2951 Vector3 oldSize = new Vector3(obPart.Scale);
2797 {
2798 Vector3 oldSize = new Vector3(obPart.Scale);
2799 2952
2800 float f = 1.0f; 2953 float f = 1.0f;
2801 float a = 1.0f; 2954 float a = 1.0f;
2802 2955
2803 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2956 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2957 {
2958 if (oldSize.X*x > m_scene.m_maxPhys)
2804 { 2959 {
2805 if (oldSize.X*x > m_scene.m_maxPhys) 2960 f = m_scene.m_maxPhys / oldSize.X;
2806 { 2961 a = f / x;
2807 f = m_scene.m_maxPhys / oldSize.X; 2962 x *= a;
2808 a = f / x; 2963 y *= a;
2809 x *= a; 2964 z *= a;
2810 y *= a;
2811 z *= a;
2812 }
2813 if (oldSize.Y*y > m_scene.m_maxPhys)
2814 {
2815 f = m_scene.m_maxPhys / oldSize.Y;
2816 a = f / y;
2817 x *= a;
2818 y *= a;
2819 z *= a;
2820 }
2821 if (oldSize.Z*z > m_scene.m_maxPhys)
2822 {
2823 f = m_scene.m_maxPhys / oldSize.Z;
2824 a = f / z;
2825 x *= a;
2826 y *= a;
2827 z *= a;
2828 }
2829 } 2965 }
2830 else 2966 if (oldSize.Y*y > m_scene.m_maxPhys)
2967 {
2968 f = m_scene.m_maxPhys / oldSize.Y;
2969 a = f / y;
2970 x *= a;
2971 y *= a;
2972 z *= a;
2973 }
2974 if (oldSize.Z*z > m_scene.m_maxPhys)
2975 {
2976 f = m_scene.m_maxPhys / oldSize.Z;
2977 a = f / z;
2978 x *= a;
2979 y *= a;
2980 z *= a;
2981 }
2982 }
2983 else
2984 {
2985 if (oldSize.X*x > m_scene.m_maxNonphys)
2986 {
2987 f = m_scene.m_maxNonphys / oldSize.X;
2988 a = f / x;
2989 x *= a;
2990 y *= a;
2991 z *= a;
2992 }
2993 if (oldSize.Y*y > m_scene.m_maxNonphys)
2831 { 2994 {
2832 if (oldSize.X*x > m_scene.m_maxNonphys) 2995 f = m_scene.m_maxNonphys / oldSize.Y;
2833 { 2996 a = f / y;
2834 f = m_scene.m_maxNonphys / oldSize.X; 2997 x *= a;
2835 a = f / x; 2998 y *= a;
2836 x *= a; 2999 z *= a;
2837 y *= a; 3000 }
2838 z *= a; 3001 if (oldSize.Z*z > m_scene.m_maxNonphys)
2839 } 3002 {
2840 if (oldSize.Y*y > m_scene.m_maxNonphys) 3003 f = m_scene.m_maxNonphys / oldSize.Z;
2841 { 3004 a = f / z;
2842 f = m_scene.m_maxNonphys / oldSize.Y; 3005 x *= a;
2843 a = f / y; 3006 y *= a;
2844 x *= a; 3007 z *= a;
2845 y *= a;
2846 z *= a;
2847 }
2848 if (oldSize.Z*z > m_scene.m_maxNonphys)
2849 {
2850 f = m_scene.m_maxNonphys / oldSize.Z;
2851 a = f / z;
2852 x *= a;
2853 y *= a;
2854 z *= a;
2855 }
2856 } 3008 }
2857 } 3009 }
2858 } 3010 }
2859 } 3011 }
2860 } 3012 }
3013 lockPartsForRead(false);
2861 3014
2862 Vector3 prevScale = part.Scale; 3015 Vector3 prevScale = part.Scale;
2863 prevScale.X *= x; 3016 prevScale.X *= x;
@@ -2865,7 +3018,7 @@ namespace OpenSim.Region.Framework.Scenes
2865 prevScale.Z *= z; 3018 prevScale.Z *= z;
2866 part.Resize(prevScale); 3019 part.Resize(prevScale);
2867 3020
2868 lock (m_parts) 3021 lockPartsForRead(true);
2869 { 3022 {
2870 foreach (SceneObjectPart obPart in m_parts.Values) 3023 foreach (SceneObjectPart obPart in m_parts.Values)
2871 { 3024 {
@@ -2884,6 +3037,7 @@ namespace OpenSim.Region.Framework.Scenes
2884 } 3037 }
2885 } 3038 }
2886 } 3039 }
3040 lockPartsForRead(false);
2887 3041
2888 if (part.PhysActor != null) 3042 if (part.PhysActor != null)
2889 { 3043 {
@@ -2964,7 +3118,7 @@ namespace OpenSim.Region.Framework.Scenes
2964 axDiff *= Quaternion.Inverse(partRotation); 3118 axDiff *= Quaternion.Inverse(partRotation);
2965 diff = axDiff; 3119 diff = axDiff;
2966 3120
2967 lock (m_parts) 3121 lockPartsForRead(true);
2968 { 3122 {
2969 foreach (SceneObjectPart obPart in m_parts.Values) 3123 foreach (SceneObjectPart obPart in m_parts.Values)
2970 { 3124 {
@@ -2974,6 +3128,7 @@ namespace OpenSim.Region.Framework.Scenes
2974 } 3128 }
2975 } 3129 }
2976 } 3130 }
3131 lockPartsForRead(false);
2977 3132
2978 AbsolutePosition = newPos; 3133 AbsolutePosition = newPos;
2979 3134
@@ -3091,7 +3246,7 @@ namespace OpenSim.Region.Framework.Scenes
3091 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3246 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3092 } 3247 }
3093 3248
3094 lock (m_parts) 3249 lockPartsForRead(true);
3095 { 3250 {
3096 foreach (SceneObjectPart prim in m_parts.Values) 3251 foreach (SceneObjectPart prim in m_parts.Values)
3097 { 3252 {
@@ -3109,6 +3264,7 @@ namespace OpenSim.Region.Framework.Scenes
3109 } 3264 }
3110 } 3265 }
3111 } 3266 }
3267 lockPartsForRead(false);
3112 3268
3113 m_rootPart.ScheduleTerseUpdate(); 3269 m_rootPart.ScheduleTerseUpdate();
3114 } 3270 }
@@ -3207,7 +3363,7 @@ namespace OpenSim.Region.Framework.Scenes
3207 if (atTargets.Count > 0) 3363 if (atTargets.Count > 0)
3208 { 3364 {
3209 uint[] localids = new uint[0]; 3365 uint[] localids = new uint[0];
3210 lock (m_parts) 3366 lockPartsForRead(true);
3211 { 3367 {
3212 localids = new uint[m_parts.Count]; 3368 localids = new uint[m_parts.Count];
3213 int cntr = 0; 3369 int cntr = 0;
@@ -3217,6 +3373,7 @@ namespace OpenSim.Region.Framework.Scenes
3217 cntr++; 3373 cntr++;
3218 } 3374 }
3219 } 3375 }
3376 lockPartsForRead(false);
3220 3377
3221 for (int ctr = 0; ctr < localids.Length; ctr++) 3378 for (int ctr = 0; ctr < localids.Length; ctr++)
3222 { 3379 {
@@ -3235,7 +3392,7 @@ namespace OpenSim.Region.Framework.Scenes
3235 { 3392 {
3236 //trigger not_at_target 3393 //trigger not_at_target
3237 uint[] localids = new uint[0]; 3394 uint[] localids = new uint[0];
3238 lock (m_parts) 3395 lockPartsForRead(true);
3239 { 3396 {
3240 localids = new uint[m_parts.Count]; 3397 localids = new uint[m_parts.Count];
3241 int cntr = 0; 3398 int cntr = 0;
@@ -3245,7 +3402,8 @@ namespace OpenSim.Region.Framework.Scenes
3245 cntr++; 3402 cntr++;
3246 } 3403 }
3247 } 3404 }
3248 3405 lockPartsForRead(false);
3406
3249 for (int ctr = 0; ctr < localids.Length; ctr++) 3407 for (int ctr = 0; ctr < localids.Length; ctr++)
3250 { 3408 {
3251 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3409 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3258,19 +3416,20 @@ namespace OpenSim.Region.Framework.Scenes
3258 public float GetMass() 3416 public float GetMass()
3259 { 3417 {
3260 float retmass = 0f; 3418 float retmass = 0f;
3261 lock (m_parts) 3419 lockPartsForRead(true);
3262 { 3420 {
3263 foreach (SceneObjectPart part in m_parts.Values) 3421 foreach (SceneObjectPart part in m_parts.Values)
3264 { 3422 {
3265 retmass += part.GetMass(); 3423 retmass += part.GetMass();
3266 } 3424 }
3267 } 3425 }
3426 lockPartsForRead(false);
3268 return retmass; 3427 return retmass;
3269 } 3428 }
3270 3429
3271 public void CheckSculptAndLoad() 3430 public void CheckSculptAndLoad()
3272 { 3431 {
3273 lock (m_parts) 3432 lockPartsForRead(true);
3274 { 3433 {
3275 if (!IsDeleted) 3434 if (!IsDeleted)
3276 { 3435 {
@@ -3295,6 +3454,7 @@ namespace OpenSim.Region.Framework.Scenes
3295 } 3454 }
3296 } 3455 }
3297 } 3456 }
3457 lockPartsForRead(false);
3298 } 3458 }
3299 3459
3300 protected void AssetReceived(string id, Object sender, AssetBase asset) 3460 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3315,7 +3475,7 @@ namespace OpenSim.Region.Framework.Scenes
3315 /// <param name="client"></param> 3475 /// <param name="client"></param>
3316 public void SetGroup(UUID GroupID, IClientAPI client) 3476 public void SetGroup(UUID GroupID, IClientAPI client)
3317 { 3477 {
3318 lock (m_parts) 3478 lockPartsForRead(true);
3319 { 3479 {
3320 foreach (SceneObjectPart part in m_parts.Values) 3480 foreach (SceneObjectPart part in m_parts.Values)
3321 { 3481 {
@@ -3325,7 +3485,7 @@ namespace OpenSim.Region.Framework.Scenes
3325 3485
3326 HasGroupChanged = true; 3486 HasGroupChanged = true;
3327 } 3487 }
3328 3488 lockPartsForRead(false);
3329 ScheduleGroupForFullUpdate(); 3489 ScheduleGroupForFullUpdate();
3330 } 3490 }
3331 3491
@@ -3344,11 +3504,12 @@ namespace OpenSim.Region.Framework.Scenes
3344 3504
3345 public void SetAttachmentPoint(byte point) 3505 public void SetAttachmentPoint(byte point)
3346 { 3506 {
3347 lock (m_parts) 3507 lockPartsForRead(true);
3348 { 3508 {
3349 foreach (SceneObjectPart part in m_parts.Values) 3509 foreach (SceneObjectPart part in m_parts.Values)
3350 part.SetAttachmentPoint(point); 3510 part.SetAttachmentPoint(point);
3351 } 3511 }
3512 lockPartsForRead(false);
3352 } 3513 }
3353 3514
3354 #region ISceneObject 3515 #region ISceneObject