diff options
-rwxr-xr-x | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 121 |
1 files changed, 69 insertions, 52 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 51392ae..e37841f 100755 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -150,21 +150,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
150 | 150 | ||
151 | protected internal void Close() | 151 | protected internal void Close() |
152 | { | 152 | { |
153 | m_scenePresencesLock.EnterWriteLock(); | 153 | bool entered = false; |
154 | try | 154 | try |
155 | { | 155 | { |
156 | m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>(); | 156 | try { } |
157 | m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>(); | 157 | finally |
158 | m_scenePresenceArray = new List<ScenePresence>(); | 158 | { |
159 | m_spArrayLastVersion = 0; | 159 | m_scenePresencesLock.EnterWriteLock(); |
160 | m_spArrayVersion = 0; | 160 | entered = true; |
161 | if (_PhyScene != null) | 161 | m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>(); |
162 | _PhyScene.OnPhysicsCrash -= physicsBasedCrash; | 162 | m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>(); |
163 | _PhyScene = null; | 163 | m_scenePresenceArray = new List<ScenePresence>(); |
164 | m_spArrayLastVersion = 0; | ||
165 | m_spArrayVersion = 0; | ||
166 | if (_PhyScene != null) | ||
167 | _PhyScene.OnPhysicsCrash -= physicsBasedCrash; | ||
168 | _PhyScene = null; | ||
169 | } | ||
164 | } | 170 | } |
165 | finally | 171 | finally |
166 | { | 172 | { |
167 | m_scenePresencesLock.ExitWriteLock(); | 173 | if(entered) |
174 | m_scenePresencesLock.ExitWriteLock(); | ||
168 | } | 175 | } |
169 | 176 | ||
170 | lock (SceneObjectGroupsByFullID) | 177 | lock (SceneObjectGroupsByFullID) |
@@ -708,32 +715,36 @@ namespace OpenSim.Region.Framework.Scenes | |||
708 | 715 | ||
709 | try | 716 | try |
710 | { | 717 | { |
711 | m_scenePresencesLock.EnterWriteLock(); | 718 | try{ } |
712 | entered = true; | 719 | finally |
720 | { | ||
721 | m_scenePresencesLock.EnterWriteLock(); | ||
722 | entered = true; | ||
713 | 723 | ||
714 | m_numChildAgents++; | 724 | m_numChildAgents++; |
715 | 725 | ||
716 | if (!m_scenePresenceMap.ContainsKey(presence.UUID)) | 726 | if (!m_scenePresenceMap.ContainsKey(presence.UUID)) |
717 | { | ||
718 | m_scenePresenceMap[presence.UUID] = presence; | ||
719 | m_scenePresenceLocalIDMap[presence.LocalId] = presence; | ||
720 | } | ||
721 | else | ||
722 | { | ||
723 | // Remember the old presence reference from the dictionary | ||
724 | ScenePresence oldref = m_scenePresenceMap[presence.UUID]; | ||
725 | uint oldLocalID = oldref.LocalId; | ||
726 | // Replace the presence reference in the dictionary with the new value | ||
727 | m_scenePresenceMap[presence.UUID] = presence; | ||
728 | if(presence.LocalId != oldLocalID) | ||
729 | { | 727 | { |
730 | m_scenePresenceLocalIDMap.TryRemove(oldLocalID, out oldref); | 728 | m_scenePresenceMap[presence.UUID] = presence; |
731 | m_scenePresenceLocalIDMap[presence.LocalId] = presence; | 729 | m_scenePresenceLocalIDMap[presence.LocalId] = presence; |
732 | } | 730 | } |
733 | // Find the index in the list where the old ref was stored and update the reference | 731 | else |
734 | } | 732 | { |
733 | // Remember the old presence reference from the dictionary | ||
734 | ScenePresence oldref = m_scenePresenceMap[presence.UUID]; | ||
735 | uint oldLocalID = oldref.LocalId; | ||
736 | // Replace the presence reference in the dictionary with the new value | ||
737 | m_scenePresenceMap[presence.UUID] = presence; | ||
738 | if(presence.LocalId != oldLocalID) | ||
739 | { | ||
740 | m_scenePresenceLocalIDMap.TryRemove(oldLocalID, out oldref); | ||
741 | m_scenePresenceLocalIDMap[presence.LocalId] = presence; | ||
742 | } | ||
743 | // Find the index in the list where the old ref was stored and update the reference | ||
744 | } | ||
735 | 745 | ||
736 | ++m_spArrayVersion; | 746 | ++m_spArrayVersion; |
747 | } | ||
737 | } | 748 | } |
738 | finally | 749 | finally |
739 | { | 750 | { |
@@ -759,19 +770,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
759 | bool entered = false; | 770 | bool entered = false; |
760 | try | 771 | try |
761 | { | 772 | { |
762 | m_scenePresencesLock.EnterWriteLock(); | 773 | try { } |
763 | entered = true; | 774 | finally |
764 | // Remove the presence reference from the dictionary | ||
765 | ScenePresence oldref; | ||
766 | if(m_scenePresenceMap.TryRemove(agentID, out oldref)) | ||
767 | { | 775 | { |
768 | // Find the index in the list where the old ref was stored and remove the reference | 776 | m_scenePresencesLock.EnterWriteLock(); |
769 | m_scenePresenceLocalIDMap.TryRemove(oldref.LocalId, out oldref); | 777 | entered = true; |
770 | ++m_spArrayVersion; | 778 | // Remove the presence reference from the dictionary |
771 | } | 779 | ScenePresence oldref; |
772 | else | 780 | if(m_scenePresenceMap.TryRemove(agentID, out oldref)) |
773 | { | 781 | { |
774 | m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); | 782 | // Find the index in the list where the old ref was stored and remove the reference |
783 | m_scenePresenceLocalIDMap.TryRemove(oldref.LocalId, out oldref); | ||
784 | ++m_spArrayVersion; | ||
785 | } | ||
786 | else | ||
787 | { | ||
788 | m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); | ||
789 | } | ||
775 | } | 790 | } |
776 | } | 791 | } |
777 | finally | 792 | finally |
@@ -905,26 +920,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
905 | protected internal List<ScenePresence> GetScenePresences() | 920 | protected internal List<ScenePresence> GetScenePresences() |
906 | { | 921 | { |
907 | bool entered = false; | 922 | bool entered = false; |
923 | List<ScenePresence> ret = new List<ScenePresence>(); | ||
908 | try | 924 | try |
909 | { | 925 | { |
910 | m_scenePresencesLock.EnterWriteLock(); | 926 | try{ } |
911 | entered = true; | 927 | finally |
912 | if(m_spArrayLastVersion != m_spArrayVersion) | ||
913 | { | 928 | { |
914 | m_scenePresenceArray = new List<ScenePresence>(m_scenePresenceMap.Values); | 929 | m_scenePresencesLock.EnterWriteLock(); |
915 | m_spArrayLastVersion = m_spArrayVersion; | 930 | entered = true; |
931 | if(m_spArrayLastVersion != m_spArrayVersion) | ||
932 | { | ||
933 | m_scenePresenceArray = new List<ScenePresence>(m_scenePresenceMap.Values); | ||
934 | m_spArrayLastVersion = m_spArrayVersion; | ||
935 | } | ||
936 | ret = m_scenePresenceArray; | ||
916 | } | 937 | } |
917 | return m_scenePresenceArray; | ||
918 | } | ||
919 | catch | ||
920 | { | ||
921 | return new List<ScenePresence>(); | ||
922 | } | 938 | } |
923 | finally | 939 | finally |
924 | { | 940 | { |
925 | if(entered) | 941 | if(entered) |
926 | m_scenePresencesLock.ExitWriteLock(); | 942 | m_scenePresencesLock.ExitWriteLock(); |
927 | } | 943 | } |
944 | return ret; | ||
928 | } | 945 | } |
929 | 946 | ||
930 | /// <summary> | 947 | /// <summary> |