diff options
author | Robert Adams | 2014-07-30 21:49:57 -0700 |
---|---|---|
committer | Robert Adams | 2014-07-30 21:49:57 -0700 |
commit | 50ed97aa1a91beb20747b5d6377390669c614450 (patch) | |
tree | 91d61a478eb0607c8e54f6712e32cebba6c9248b | |
parent | Fix bug where calling PUTGROUP on the core groups service without specifying ... (diff) | |
download | opensim-SC_OLD-50ed97aa1a91beb20747b5d6377390669c614450.zip opensim-SC_OLD-50ed97aa1a91beb20747b5d6377390669c614450.tar.gz opensim-SC_OLD-50ed97aa1a91beb20747b5d6377390669c614450.tar.bz2 opensim-SC_OLD-50ed97aa1a91beb20747b5d6377390669c614450.tar.xz |
BulletSim: thread safe handling of list of avatars.
Fix for 7284 which is an enumeration exception when starting up a region.
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index e517389..f7317c0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -471,7 +471,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
471 | // We must generate a collision for avatars whether they collide or not. | 471 | // We must generate a collision for avatars whether they collide or not. |
472 | // This is required by OpenSim to update avatar animations, etc. | 472 | // This is required by OpenSim to update avatar animations, etc. |
473 | lock (m_avatars) | 473 | lock (m_avatars) |
474 | m_avatars.Add(actor); | 474 | { |
475 | // The funky copy is because this list has few and infrequent changes but is | ||
476 | // read zillions of times. This allows the reader/iterator to use the | ||
477 | // list and this creates a new list with any updates. | ||
478 | HashSet<BSPhysObject> avatarTemp = new HashSet<BSPhysObject>(m_avatars); | ||
479 | avatarTemp.Add(actor); | ||
480 | m_avatars = avatarTemp; | ||
481 | } | ||
475 | 482 | ||
476 | return actor; | 483 | return actor; |
477 | } | 484 | } |
@@ -491,7 +498,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
491 | PhysObjects.Remove(bsactor.LocalID); | 498 | PhysObjects.Remove(bsactor.LocalID); |
492 | // Remove kludge someday | 499 | // Remove kludge someday |
493 | lock (m_avatars) | 500 | lock (m_avatars) |
494 | m_avatars.Remove(bsactor); | 501 | { |
502 | HashSet<BSPhysObject> avatarTemp = new HashSet<BSPhysObject>(m_avatars); | ||
503 | avatarTemp.Remove(bsactor); | ||
504 | m_avatars = avatarTemp; | ||
505 | } | ||
495 | } | 506 | } |
496 | catch (Exception e) | 507 | catch (Exception e) |
497 | { | 508 | { |
@@ -736,9 +747,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
736 | // The simulator expects collisions for avatars even if there are have been no collisions. | 747 | // The simulator expects collisions for avatars even if there are have been no collisions. |
737 | // The event updates avatar animations and stuff. | 748 | // The event updates avatar animations and stuff. |
738 | // If you fix avatar animation updates, remove this overhead and let normal collision processing happen. | 749 | // If you fix avatar animation updates, remove this overhead and let normal collision processing happen. |
739 | foreach (BSPhysObject bsp in m_avatars) | 750 | // Note that we copy the root of the list to search. Any updates will create a new list |
751 | // thus freeing this code from having to do an extra lock for every collision. | ||
752 | HashSet<BSPhysObject> avatarTemp = m_avatars; | ||
753 | foreach (BSPhysObject bsp in avatarTemp) | ||
740 | if (!ObjectsWithCollisions.Contains(bsp)) // don't call avatars twice | 754 | if (!ObjectsWithCollisions.Contains(bsp)) // don't call avatars twice |
741 | bsp.SendCollisions(); | 755 | bsp.SendCollisions(); |
756 | avatarTemp = null; | ||
742 | 757 | ||
743 | // Objects that are done colliding are removed from the ObjectsWithCollisions list. | 758 | // Objects that are done colliding are removed from the ObjectsWithCollisions list. |
744 | // Not done above because it is inside an iteration of ObjectWithCollisions. | 759 | // Not done above because it is inside an iteration of ObjectWithCollisions. |