diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 80 |
1 files changed, 72 insertions, 8 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index ce11267..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) |
@@ -225,6 +234,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
225 | protected internal bool AddRestoredSceneObject( | 234 | protected internal bool AddRestoredSceneObject( |
226 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) | 235 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) |
227 | { | 236 | { |
237 | // KF: Check for out-of-region, move inside and make static. | ||
238 | Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, | ||
239 | sceneObject.RootPart.GroupPosition.Y, | ||
240 | sceneObject.RootPart.GroupPosition.Z); | ||
241 | if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 || | ||
242 | npos.X > Constants.RegionSize || | ||
243 | npos.Y > Constants.RegionSize)) | ||
244 | { | ||
245 | if (npos.X < 0.0) npos.X = 1.0f; | ||
246 | if (npos.Y < 0.0) npos.Y = 1.0f; | ||
247 | if (npos.Z < 0.0) npos.Z = 0.0f; | ||
248 | if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f; | ||
249 | if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f; | ||
250 | |||
251 | foreach (SceneObjectPart part in sceneObject.Children.Values) | ||
252 | { | ||
253 | part.GroupPosition = npos; | ||
254 | } | ||
255 | sceneObject.RootPart.Velocity = Vector3.Zero; | ||
256 | sceneObject.RootPart.AngularVelocity = Vector3.Zero; | ||
257 | sceneObject.RootPart.Acceleration = Vector3.Zero; | ||
258 | sceneObject.RootPart.Velocity = Vector3.Zero; | ||
259 | } | ||
260 | |||
228 | if (!alreadyPersisted) | 261 | if (!alreadyPersisted) |
229 | { | 262 | { |
230 | sceneObject.ForceInventoryPersistence(); | 263 | sceneObject.ForceInventoryPersistence(); |
@@ -518,7 +551,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
518 | 551 | ||
519 | Entities[presence.UUID] = presence; | 552 | Entities[presence.UUID] = presence; |
520 | 553 | ||
521 | lock (m_scenePresences) | 554 | m_scenePresencesLock.EnterWriteLock(); |
555 | try | ||
522 | { | 556 | { |
523 | if (!m_scenePresences.ContainsKey(presence.UUID)) | 557 | if (!m_scenePresences.ContainsKey(presence.UUID)) |
524 | { | 558 | { |
@@ -530,11 +564,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
530 | Array.Copy(m_scenePresenceArray, newArray, oldLength); | 564 | Array.Copy(m_scenePresenceArray, newArray, oldLength); |
531 | newArray[oldLength] = presence; | 565 | newArray[oldLength] = presence; |
532 | m_scenePresenceArray = newArray; | 566 | m_scenePresenceArray = newArray; |
567 | m_scenePresenceList = new List<ScenePresence>(m_scenePresenceArray); | ||
533 | } | 568 | } |
534 | else | 569 | else |
535 | { | 570 | { |
536 | m_scenePresences[presence.UUID] = presence; | 571 | m_scenePresences[presence.UUID] = presence; |
537 | 572 | ||
538 | // Do a linear search through the array of ScenePresence references | 573 | // Do a linear search through the array of ScenePresence references |
539 | // and update the modified entry | 574 | // and update the modified entry |
540 | for (int i = 0; i < m_scenePresenceArray.Length; i++) | 575 | for (int i = 0; i < m_scenePresenceArray.Length; i++) |
@@ -545,8 +580,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
545 | break; | 580 | break; |
546 | } | 581 | } |
547 | } | 582 | } |
583 | m_scenePresenceList = new List<ScenePresence>(m_scenePresenceArray); | ||
548 | } | 584 | } |
549 | } | 585 | } |
586 | finally | ||
587 | { | ||
588 | m_scenePresencesLock.ExitWriteLock(); | ||
589 | } | ||
550 | } | 590 | } |
551 | 591 | ||
552 | /// <summary> | 592 | /// <summary> |
@@ -561,7 +601,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
561 | agentID); | 601 | agentID); |
562 | } | 602 | } |
563 | 603 | ||
564 | lock (m_scenePresences) | 604 | m_scenePresencesLock.EnterWriteLock(); |
605 | try | ||
565 | { | 606 | { |
566 | if (m_scenePresences.Remove(agentID)) | 607 | if (m_scenePresences.Remove(agentID)) |
567 | { | 608 | { |
@@ -580,12 +621,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
580 | } | 621 | } |
581 | } | 622 | } |
582 | m_scenePresenceArray = newArray; | 623 | m_scenePresenceArray = newArray; |
624 | m_scenePresenceList = new List<ScenePresence>(m_scenePresenceArray); | ||
583 | } | 625 | } |
584 | else | 626 | else |
585 | { | 627 | { |
586 | 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); |
587 | } | 629 | } |
588 | } | 630 | } |
631 | finally | ||
632 | { | ||
633 | m_scenePresencesLock.ExitWriteLock(); | ||
634 | } | ||
589 | } | 635 | } |
590 | 636 | ||
591 | protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) | 637 | protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) |
@@ -706,8 +752,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
706 | /// <returns></returns> | 752 | /// <returns></returns> |
707 | private List<ScenePresence> GetScenePresences() | 753 | private List<ScenePresence> GetScenePresences() |
708 | { | 754 | { |
709 | lock (m_scenePresences) | 755 | m_scenePresencesLock.EnterReadLock(); |
710 | return new List<ScenePresence>(m_scenePresenceArray); | 756 | try |
757 | { | ||
758 | return m_scenePresenceList; | ||
759 | } | ||
760 | finally | ||
761 | { | ||
762 | m_scenePresencesLock.ExitReadLock(); | ||
763 | } | ||
711 | } | 764 | } |
712 | 765 | ||
713 | /// <summary> | 766 | /// <summary> |
@@ -718,10 +771,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
718 | protected internal ScenePresence GetScenePresence(UUID agentID) | 771 | protected internal ScenePresence GetScenePresence(UUID agentID) |
719 | { | 772 | { |
720 | ScenePresence sp; | 773 | ScenePresence sp; |
721 | lock (m_scenePresences) | 774 | m_scenePresencesLock.EnterReadLock(); |
775 | try | ||
722 | { | 776 | { |
723 | m_scenePresences.TryGetValue(agentID, out sp); | 777 | m_scenePresences.TryGetValue(agentID, out sp); |
724 | } | 778 | } |
779 | finally | ||
780 | { | ||
781 | m_scenePresencesLock.ExitReadLock(); | ||
782 | } | ||
725 | return sp; | 783 | return sp; |
726 | } | 784 | } |
727 | 785 | ||
@@ -756,10 +814,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
756 | 814 | ||
757 | protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) | 815 | protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) |
758 | { | 816 | { |
759 | lock (m_scenePresences) | 817 | m_scenePresencesLock.EnterReadLock(); |
818 | try | ||
760 | { | 819 | { |
761 | m_scenePresences.TryGetValue(agentID, out avatar); | 820 | m_scenePresences.TryGetValue(agentID, out avatar); |
762 | } | 821 | } |
822 | finally | ||
823 | { | ||
824 | m_scenePresencesLock.ExitReadLock(); | ||
825 | } | ||
763 | return (avatar != null); | 826 | return (avatar != null); |
764 | } | 827 | } |
765 | 828 | ||
@@ -1037,6 +1100,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1037 | Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction); | 1100 | Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction); |
1038 | */ | 1101 | */ |
1039 | // For now, perform actiona serially | 1102 | // For now, perform actiona serially |
1103 | |||
1040 | foreach (ScenePresence sp in GetScenePresences()) | 1104 | foreach (ScenePresence sp in GetScenePresences()) |
1041 | { | 1105 | { |
1042 | try | 1106 | try |