diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index f43de20..c16ba12 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -70,6 +70,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
70 | 70 | ||
71 | protected Dictionary<UUID, ScenePresence> m_scenePresences = new Dictionary<UUID, ScenePresence>(); | 71 | protected Dictionary<UUID, ScenePresence> m_scenePresences = new Dictionary<UUID, ScenePresence>(); |
72 | protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0]; | 72 | protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0]; |
73 | protected List<ScenePresence> m_scenePresenceList = new List<ScenePresence>(); | ||
74 | |||
75 | protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim(); | ||
73 | 76 | ||
74 | // SceneObjects is not currently populated or used. | 77 | // SceneObjects is not currently populated or used. |
75 | //public Dictionary<UUID, SceneObjectGroup> SceneObjects; | 78 | //public Dictionary<UUID, SceneObjectGroup> SceneObjects; |
@@ -132,10 +135,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
132 | 135 | ||
133 | protected internal void Close() | 136 | protected internal void Close() |
134 | { | 137 | { |
135 | lock (m_scenePresences) | 138 | m_scenePresencesLock.EnterWriteLock(); |
139 | try | ||
136 | { | 140 | { |
137 | m_scenePresences.Clear(); | 141 | m_scenePresences.Clear(); |
138 | m_scenePresenceArray = new ScenePresence[0]; | 142 | m_scenePresenceArray = new ScenePresence[0]; |
143 | m_scenePresenceList = new List<ScenePresence>(); | ||
144 | } | ||
145 | finally | ||
146 | { | ||
147 | m_scenePresencesLock.ExitWriteLock(); | ||
139 | } | 148 | } |
140 | 149 | ||
141 | lock (m_dictionary_lock) | 150 | lock (m_dictionary_lock) |
@@ -542,7 +551,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
542 | 551 | ||
543 | Entities[presence.UUID] = presence; | 552 | Entities[presence.UUID] = presence; |
544 | 553 | ||
545 | lock (m_scenePresences) | 554 | m_scenePresencesLock.EnterWriteLock(); |
555 | try | ||
546 | { | 556 | { |
547 | if (!m_scenePresences.ContainsKey(presence.UUID)) | 557 | if (!m_scenePresences.ContainsKey(presence.UUID)) |
548 | { | 558 | { |
@@ -554,11 +564,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
554 | Array.Copy(m_scenePresenceArray, newArray, oldLength); | 564 | Array.Copy(m_scenePresenceArray, newArray, oldLength); |
555 | newArray[oldLength] = presence; | 565 | newArray[oldLength] = presence; |
556 | m_scenePresenceArray = newArray; | 566 | m_scenePresenceArray = newArray; |
567 | m_scenePresenceList = new List<ScenePresence>(m_scenePresenceArray); | ||
557 | } | 568 | } |
558 | else | 569 | else |
559 | { | 570 | { |
560 | m_scenePresences[presence.UUID] = presence; | 571 | m_scenePresences[presence.UUID] = presence; |
561 | 572 | ||
562 | // Do a linear search through the array of ScenePresence references | 573 | // Do a linear search through the array of ScenePresence references |
563 | // and update the modified entry | 574 | // and update the modified entry |
564 | for (int i = 0; i < m_scenePresenceArray.Length; i++) | 575 | for (int i = 0; i < m_scenePresenceArray.Length; i++) |
@@ -569,8 +580,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
569 | break; | 580 | break; |
570 | } | 581 | } |
571 | } | 582 | } |
583 | m_scenePresenceList = new List<ScenePresence>(m_scenePresenceArray); | ||
572 | } | 584 | } |
573 | } | 585 | } |
586 | finally | ||
587 | { | ||
588 | m_scenePresencesLock.ExitWriteLock(); | ||
589 | } | ||
574 | } | 590 | } |
575 | 591 | ||
576 | /// <summary> | 592 | /// <summary> |
@@ -585,7 +601,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
585 | agentID); | 601 | agentID); |
586 | } | 602 | } |
587 | 603 | ||
588 | lock (m_scenePresences) | 604 | m_scenePresencesLock.EnterWriteLock(); |
605 | try | ||
589 | { | 606 | { |
590 | if (m_scenePresences.Remove(agentID)) | 607 | if (m_scenePresences.Remove(agentID)) |
591 | { | 608 | { |
@@ -604,12 +621,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
604 | } | 621 | } |
605 | } | 622 | } |
606 | m_scenePresenceArray = newArray; | 623 | m_scenePresenceArray = newArray; |
624 | m_scenePresenceList = new List<ScenePresence>(m_scenePresenceArray); | ||
607 | } | 625 | } |
608 | else | 626 | else |
609 | { | 627 | { |
610 | m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); | 628 | m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); |
611 | } | 629 | } |
612 | } | 630 | } |
631 | finally | ||
632 | { | ||
633 | m_scenePresencesLock.ExitWriteLock(); | ||
634 | } | ||
613 | } | 635 | } |
614 | 636 | ||
615 | protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) | 637 | protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) |
@@ -730,8 +752,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
730 | /// <returns></returns> | 752 | /// <returns></returns> |
731 | private List<ScenePresence> GetScenePresences() | 753 | private List<ScenePresence> GetScenePresences() |
732 | { | 754 | { |
733 | lock (m_scenePresences) | 755 | m_scenePresencesLock.EnterReadLock(); |
734 | return new List<ScenePresence>(m_scenePresenceArray); | 756 | try |
757 | { | ||
758 | return m_scenePresenceList; | ||
759 | } | ||
760 | finally | ||
761 | { | ||
762 | m_scenePresencesLock.ExitReadLock(); | ||
763 | } | ||
735 | } | 764 | } |
736 | 765 | ||
737 | /// <summary> | 766 | /// <summary> |
@@ -742,10 +771,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
742 | protected internal ScenePresence GetScenePresence(UUID agentID) | 771 | protected internal ScenePresence GetScenePresence(UUID agentID) |
743 | { | 772 | { |
744 | ScenePresence sp; | 773 | ScenePresence sp; |
745 | lock (m_scenePresences) | 774 | m_scenePresencesLock.EnterReadLock(); |
775 | try | ||
746 | { | 776 | { |
747 | m_scenePresences.TryGetValue(agentID, out sp); | 777 | m_scenePresences.TryGetValue(agentID, out sp); |
748 | } | 778 | } |
779 | finally | ||
780 | { | ||
781 | m_scenePresencesLock.ExitReadLock(); | ||
782 | } | ||
749 | return sp; | 783 | return sp; |
750 | } | 784 | } |
751 | 785 | ||
@@ -780,10 +814,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
780 | 814 | ||
781 | protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) | 815 | protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) |
782 | { | 816 | { |
783 | lock (m_scenePresences) | 817 | m_scenePresencesLock.EnterReadLock(); |
818 | try | ||
784 | { | 819 | { |
785 | m_scenePresences.TryGetValue(agentID, out avatar); | 820 | m_scenePresences.TryGetValue(agentID, out avatar); |
786 | } | 821 | } |
822 | finally | ||
823 | { | ||
824 | m_scenePresencesLock.ExitReadLock(); | ||
825 | } | ||
787 | return (avatar != null); | 826 | return (avatar != null); |
788 | } | 827 | } |
789 | 828 | ||
@@ -1061,6 +1100,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1061 | Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction); | 1100 | Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction); |
1062 | */ | 1101 | */ |
1063 | // For now, perform actiona serially | 1102 | // For now, perform actiona serially |
1103 | |||
1064 | foreach (ScenePresence sp in GetScenePresences()) | 1104 | foreach (ScenePresence sp in GetScenePresences()) |
1065 | { | 1105 | { |
1066 | try | 1106 | try |