aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
diff options
context:
space:
mode:
authorRobert Adams2015-08-09 15:36:50 -0700
committerRobert Adams2015-08-09 15:36:50 -0700
commitfe37cb999055c0df27a3fc1e038013575a63e2ea (patch)
tree341307fa0ad9aee33a319cbb6c4d82a0f7cebe16 /OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
parentBulletSim: update the motion actors so they completely clean themselves (diff)
downloadopensim-SC-fe37cb999055c0df27a3fc1e038013575a63e2ea.zip
opensim-SC-fe37cb999055c0df27a3fc1e038013575a63e2ea.tar.gz
opensim-SC-fe37cb999055c0df27a3fc1e038013575a63e2ea.tar.bz2
opensim-SC-fe37cb999055c0df27a3fc1e038013575a63e2ea.tar.xz
BulletSim: rearrange code and add different locking to eliminate chances
of race conditions and, especially, race conditions when an object is removed and quickly re-added to a scene. This hopefully reduces the occurance of problems when avatars TP within a region -- the main problem being the loss of collisions.
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSScene.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs51
1 files changed, 25 insertions, 26 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index f8e8f57..1a95f91 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -76,7 +76,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
76 76
77 // Keep track of all the avatars so we can send them a collision event 77 // Keep track of all the avatars so we can send them a collision event
78 // every tick so OpenSim will update its animation. 78 // every tick so OpenSim will update its animation.
79 private HashSet<BSPhysObject> m_avatars = new HashSet<BSPhysObject>(); 79 private HashSet<BSPhysObject> AvatarsInScene = new HashSet<BSPhysObject>();
80 private Object AvatarsInSceneLock = new Object();
80 81
81 // let my minuions use my logger 82 // let my minuions use my logger
82 public ILog Logger { get { return m_log; } } 83 public ILog Logger { get { return m_log; } }
@@ -425,11 +426,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
425 // make sure no stepping happens while we're deleting stuff 426 // make sure no stepping happens while we're deleting stuff
426 m_initialized = false; 427 m_initialized = false;
427 428
428 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects) 429 lock (PhysObjects)
429 { 430 {
430 kvp.Value.Destroy(); 431 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
432 {
433 kvp.Value.Destroy();
434 }
435 PhysObjects.Clear();
431 } 436 }
432 PhysObjects.Clear();
433 437
434 // Now that the prims are all cleaned up, there should be no constraints left 438 // Now that the prims are all cleaned up, there should be no constraints left
435 if (Constraints != null) 439 if (Constraints != null)
@@ -480,15 +484,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
480 // TODO: Remove kludge someday. 484 // TODO: Remove kludge someday.
481 // We must generate a collision for avatars whether they collide or not. 485 // We must generate a collision for avatars whether they collide or not.
482 // This is required by OpenSim to update avatar animations, etc. 486 // This is required by OpenSim to update avatar animations, etc.
483 lock (m_avatars) 487 lock (AvatarsInSceneLock)
484 { 488 AvatarsInScene.Add(actor);
485 // The funky copy is because this list has few and infrequent changes but is
486 // read zillions of times. This allows the reader/iterator to use the
487 // list and this creates a new list with any updates.
488 HashSet<BSPhysObject> avatarTemp = new HashSet<BSPhysObject>(m_avatars);
489 avatarTemp.Add(actor);
490 m_avatars = avatarTemp;
491 }
492 489
493 return actor; 490 return actor;
494 } 491 }
@@ -507,12 +504,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
507 lock (PhysObjects) 504 lock (PhysObjects)
508 PhysObjects.Remove(bsactor.LocalID); 505 PhysObjects.Remove(bsactor.LocalID);
509 // Remove kludge someday 506 // Remove kludge someday
510 lock (m_avatars) 507 lock (AvatarsInSceneLock)
511 { 508 AvatarsInScene.Remove(bsactor);
512 HashSet<BSPhysObject> avatarTemp = new HashSet<BSPhysObject>(m_avatars);
513 avatarTemp.Remove(bsactor);
514 m_avatars = avatarTemp;
515 }
516 } 509 }
517 catch (Exception e) 510 catch (Exception e)
518 { 511 {
@@ -757,13 +750,18 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
757 // The simulator expects collisions for avatars even if there are have been no collisions. 750 // The simulator expects collisions for avatars even if there are have been no collisions.
758 // The event updates avatar animations and stuff. 751 // The event updates avatar animations and stuff.
759 // If you fix avatar animation updates, remove this overhead and let normal collision processing happen. 752 // If you fix avatar animation updates, remove this overhead and let normal collision processing happen.
760 // Note that we copy the root of the list to search. Any updates will create a new list 753 // Note that we get a copy of the list to search because SendCollision() can take a while.
761 // thus freeing this code from having to do an extra lock for every collision. 754 HashSet<BSPhysObject> tempAvatarsInScene;
762 HashSet<BSPhysObject> avatarTemp = m_avatars; 755 lock (AvatarsInSceneLock)
763 foreach (BSPhysObject bsp in avatarTemp) 756 {
764 if (!ObjectsWithCollisions.Contains(bsp)) // don't call avatars twice 757 tempAvatarsInScene = new HashSet<BSPhysObject>(AvatarsInScene);
765 bsp.SendCollisions(); 758 }
766 avatarTemp = null; 759 foreach (BSPhysObject actor in tempAvatarsInScene)
760 {
761 if (!ObjectsWithCollisions.Contains(actor)) // don't call avatars twice
762 actor.SendCollisions();
763 }
764 tempAvatarsInScene = null;
767 765
768 // Objects that are done colliding are removed from the ObjectsWithCollisions list. 766 // Objects that are done colliding are removed from the ObjectsWithCollisions list.
769 // Not done above because it is inside an iteration of ObjectWithCollisions. 767 // Not done above because it is inside an iteration of ObjectWithCollisions.
@@ -813,6 +811,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
813 } 811 }
814 812
815 BSPhysObject collider; 813 BSPhysObject collider;
814 // NOTE that PhysObjects was locked before the call to SendCollision().
816 if (!PhysObjects.TryGetValue(localID, out collider)) 815 if (!PhysObjects.TryGetValue(localID, out collider))
817 { 816 {
818 // If the object that is colliding cannot be found, just ignore the collision. 817 // If the object that is colliding cannot be found, just ignore the collision.