diff options
author | Robert Adams | 2015-08-09 15:36:50 -0700 |
---|---|---|
committer | Robert Adams | 2015-08-09 15:36:50 -0700 |
commit | fe37cb999055c0df27a3fc1e038013575a63e2ea (patch) | |
tree | 341307fa0ad9aee33a319cbb6c4d82a0f7cebe16 /OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |
parent | BulletSim: update the motion actors so they completely clean themselves (diff) | |
download | opensim-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.cs | 51 |
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. |