aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
authorDan Lake2010-03-19 05:51:16 -0700
committerJohn Hurliman2010-03-19 15:16:35 -0700
commit859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046 (patch)
treedcce6c74d201b52c1a04ec9ec2cb90ce068fc020 /OpenSim/Region/Framework
parentInconsistent locking of ScenePresence array in SceneGraph. Fixed by eliminati... (diff)
downloadopensim-SC_OLD-859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046.zip
opensim-SC_OLD-859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046.tar.gz
opensim-SC_OLD-859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046.tar.bz2
opensim-SC_OLD-859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046.tar.xz
Cleaned up access to scenepresences in scenegraph. GetScenePresences and GetAvatars have been removed to consolidate locking and iteration within SceneGraph. All callers which used these to then iterate over presences have been refactored to instead pass their delegates to Scene.ForEachScenePresence(Action<ScenePresence>).
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs81
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs186
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs58
5 files changed, 147 insertions, 203 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index a86a33c..4b97e39 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -3269,7 +3269,7 @@ namespace OpenSim.Region.Framework.Scenes
3269 } 3269 }
3270 } 3270 }
3271 3271
3272 ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID); 3272 ScenePresence sp = GetScenePresence(agent.AgentID);
3273 if (sp != null) 3273 if (sp != null)
3274 { 3274 {
3275 m_log.DebugFormat( 3275 m_log.DebugFormat(
@@ -3561,8 +3561,7 @@ namespace OpenSim.Region.Framework.Scenes
3561 /// <param name="message">message to display to the user. Reason for being logged off</param> 3561 /// <param name="message">message to display to the user. Reason for being logged off</param>
3562 public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message) 3562 public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message)
3563 { 3563 {
3564 ScenePresence loggingOffUser = null; 3564 ScenePresence loggingOffUser = GetScenePresence(AvatarID);
3565 loggingOffUser = GetScenePresence(AvatarID);
3566 if (loggingOffUser != null) 3565 if (loggingOffUser != null)
3567 { 3566 {
3568 UUID localRegionSecret = UUID.Zero; 3567 UUID localRegionSecret = UUID.Zero;
@@ -3598,8 +3597,8 @@ namespace OpenSim.Region.Framework.Scenes
3598 /// <param name="isFlying"></param> 3597 /// <param name="isFlying"></param>
3599 public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) 3598 public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying)
3600 { 3599 {
3601 ScenePresence presence; 3600 ScenePresence presence = GetScenePresence(agentID);
3602 if(m_sceneGraph.TryGetAvatar(agentID, out presence)) 3601 if(presence != null)
3603 { 3602 {
3604 try 3603 try
3605 { 3604 {
@@ -3773,8 +3772,8 @@ namespace OpenSim.Region.Framework.Scenes
3773 public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, 3772 public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position,
3774 Vector3 lookAt, uint teleportFlags) 3773 Vector3 lookAt, uint teleportFlags)
3775 { 3774 {
3776 ScenePresence sp; 3775 ScenePresence sp = GetScenePresence(remoteClient.AgentId);
3777 if(m_sceneGraph.TryGetAvatar(remoteClient.AgentId, out sp)) 3776 if (sp != null)
3778 { 3777 {
3779 uint regionX = m_regInfo.RegionLocX; 3778 uint regionX = m_regInfo.RegionLocX;
3780 uint regionY = m_regInfo.RegionLocY; 3779 uint regionY = m_regInfo.RegionLocY;
@@ -3952,17 +3951,17 @@ namespace OpenSim.Region.Framework.Scenes
3952 m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}", "Firstname", "Lastname", 3951 m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}", "Firstname", "Lastname",
3953 "Agent ID", "Session ID", "Circuit", "IP", "World"); 3952 "Agent ID", "Session ID", "Circuit", "IP", "World");
3954 3953
3955 foreach (ScenePresence scenePresence in GetAvatars()) 3954 ForEachScenePresence(delegate(ScenePresence sp)
3956 { 3955 {
3957 m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16},{5,-16}{6,-16}", 3956 m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16},{5,-16}{6,-16}",
3958 scenePresence.Firstname, 3957 sp.Firstname,
3959 scenePresence.Lastname, 3958 sp.Lastname,
3960 scenePresence.UUID, 3959 sp.UUID,
3961 scenePresence.ControllingClient.AgentId, 3960 sp.ControllingClient.AgentId,
3962 "Unknown", 3961 "Unknown",
3963 "Unknown", 3962 "Unknown",
3964 RegionInfo.RegionName); 3963 RegionInfo.RegionName);
3965 } 3964 });
3966 3965
3967 break; 3966 break;
3968 } 3967 }
@@ -4128,72 +4127,42 @@ namespace OpenSim.Region.Framework.Scenes
4128 m_sceneGraph.RemovePhysicalPrim(num); 4127 m_sceneGraph.RemovePhysicalPrim(num);
4129 } 4128 }
4130 4129
4131 //The idea is to have a group of method that return a list of avatars meeting some requirement 4130 public int GetRootAgentCount()
4132 // ie it could be all m_scenePresences within a certain range of the calling prim/avatar.
4133 //
4134 // GetAvatars returns a new list of all root agent presences in the scene
4135 // GetScenePresences returns a new list of all presences in the scene or a filter may be passed.
4136 // GetScenePresence returns the presence with matching UUID or first/last name.
4137 // ForEachScenePresence requests the Scene to run a delegate function against all presences.
4138
4139 /// <summary>
4140 /// Return a list of all avatars in this region.
4141 /// This list is a new object, so it can be iterated over without locking.
4142 /// </summary>
4143 /// <returns></returns>
4144 public List<ScenePresence> GetAvatars()
4145 {
4146 return m_sceneGraph.GetAvatars();
4147 }
4148
4149 /// <summary>
4150 /// Return a list of all ScenePresences in this region. This returns child agents as well as root agents.
4151 /// This list is a new object, so it can be iterated over without locking.
4152 /// </summary>
4153 /// <returns></returns>
4154 public List<ScenePresence> GetScenePresences()
4155 { 4131 {
4156 return m_sceneGraph.GetScenePresences(); 4132 return m_sceneGraph.GetRootAgentCount();
4157 } 4133 }
4158 4134
4159 /// <summary> 4135 public int GetChildAgentCount()
4160 /// Request a filtered list of ScenePresences in this region.
4161 /// This list is a new object, so it can be iterated over without locking.
4162 /// </summary>
4163 /// <param name="filter"></param>
4164 /// <returns></returns>
4165 public List<ScenePresence> GetScenePresences(FilterAvatarList filter)
4166 { 4136 {
4167 return m_sceneGraph.GetScenePresences(filter); 4137 return m_sceneGraph.GetChildAgentCount();
4168 } 4138 }
4169 4139
4170 /// <summary> 4140 /// <summary>
4171 /// Request a scene presence by UUID 4141 /// Request a scene presence by UUID. Fast, indexed lookup.
4172 /// </summary> 4142 /// </summary>
4173 /// <param name="avatarID"></param> 4143 /// <param name="agentID"></param>
4174 /// <returns></returns> 4144 /// <returns>null if the presence was not found</returns>
4175 public ScenePresence GetScenePresence(UUID avatarID) 4145 public ScenePresence GetScenePresence(UUID agentID)
4176 { 4146 {
4177 return m_sceneGraph.GetScenePresence(avatarID); 4147 return m_sceneGraph.GetScenePresence(agentID);
4178 } 4148 }
4179 4149
4180 /// <summary> 4150 /// <summary>
4181 /// Request the ScenePresence in this region by first/last name. 4151 /// Request the scene presence by name.
4182 /// Should normally only be a single match, but first is always returned
4183 /// </summary> 4152 /// </summary>
4184 /// <param name="firstName"></param> 4153 /// <param name="firstName"></param>
4185 /// <param name="lastName"></param> 4154 /// <param name="lastName"></param>
4186 /// <returns></returns> 4155 /// <returns>null if the presence was not found</returns>
4187 public ScenePresence GetScenePresence(string firstName, string lastName) 4156 public ScenePresence GetScenePresence(string firstName, string lastName)
4188 { 4157 {
4189 return m_sceneGraph.GetScenePresence(firstName, lastName); 4158 return m_sceneGraph.GetScenePresence(firstName, lastName);
4190 } 4159 }
4191 4160
4192 /// <summary> 4161 /// <summary>
4193 /// Request the ScenePresence in this region by localID. 4162 /// Request the scene presence by localID.
4194 /// </summary> 4163 /// </summary>
4195 /// <param name="localID"></param> 4164 /// <param name="localID"></param>
4196 /// <returns></returns> 4165 /// <returns>null if the presence was not found</returns>
4197 public ScenePresence GetScenePresence(uint localID) 4166 public ScenePresence GetScenePresence(uint localID)
4198 { 4167 {
4199 return m_sceneGraph.GetScenePresence(localID); 4168 return m_sceneGraph.GetScenePresence(localID);
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index d259c42..b6e5995 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -699,116 +699,84 @@ namespace OpenSim.Region.Framework.Scenes
699 return null; 699 return null;
700 } 700 }
701 701
702 // The idea is to have a group of method that return a list of avatars meeting some requirement
703 // ie it could be all m_scenePresences within a certain range of the calling prim/avatar.
704 //
705 // GetAvatars returns a new list of all root agent presences in the scene
706 // GetScenePresences returns a new list of all presences in the scene or a filter may be passed.
707 // GetScenePresence returns the presence with matching UUID or the first presence matching the passed filter.
708 // ForEachScenePresence requests the Scene to run a delegate function against all presences.
709
710 /// <summary> 702 /// <summary>
711 /// Request a list of all avatars in this region (no child agents) 703 /// Request a copy of m_scenePresences in this World
712 /// This list is a new object, so it can be iterated over without locking. 704 /// There is no guarantee that presences will remain in the scene after the list is returned.
705 /// This list should remain private to SceneGraph. Callers wishing to iterate should instead
706 /// pass a delegate to ForEachScenePresence.
713 /// </summary> 707 /// </summary>
714 /// <returns></returns> 708 /// <returns></returns>
715 public List<ScenePresence> GetAvatars() 709 private List<ScenePresence> GetScenePresences()
716 { 710 {
717 return GetScenePresences(delegate(ScenePresence scenePresence) 711 lock (m_scenePresences)
718 { 712 return new List<ScenePresence>(m_scenePresenceArray);
719 return !scenePresence.IsChildAgent;
720 });
721 } 713 }
722 714
723 /// <summary> 715 /// <summary>
724 /// Request a list of m_scenePresences in this World 716 /// Request a scene presence by UUID. Fast, indexed lookup.
725 /// Returns a copy so it can be iterated without a lock.
726 /// There is no guarantee that presences will remain in the scene after the list is returned.
727 /// </summary> 717 /// </summary>
728 /// <returns></returns> 718 /// <param name="agentID"></param>
729 protected internal List<ScenePresence> GetScenePresences() 719 /// <returns>null if the presence was not found</returns>
720 protected internal ScenePresence GetScenePresence(UUID agentID)
730 { 721 {
731 List<ScenePresence> result; 722 ScenePresence sp;
732 lock (m_scenePresences) 723 lock (m_scenePresences)
733 { 724 {
734 result = new List<ScenePresence>(m_scenePresenceArray.Length); 725 m_scenePresences.TryGetValue(agentID, out sp);
735 result.AddRange(m_scenePresenceArray);
736 } 726 }
737 return result; 727 return sp;
738 } 728 }
739 729
740 /// <summary> 730 /// <summary>
741 /// Request a filtered list of m_scenePresences in this World 731 /// Request the scene presence by name.
742 /// Returns a copy so it can be iterated without a lock.
743 /// There is no guarantee that presences will remain in the scene after the list is returned.
744 /// </summary> 732 /// </summary>
745 /// <returns></returns> 733 /// <param name="firstName"></param>
746 protected internal List<ScenePresence> GetScenePresences(FilterAvatarList filter) 734 /// <param name="lastName"></param>
735 /// <returns>null if the presence was not found</returns>
736 protected internal ScenePresence GetScenePresence(string firstName, string lastName)
747 { 737 {
748 List<ScenePresence> result = new List<ScenePresence>(); 738 foreach (ScenePresence presence in GetScenePresences())
749 // Check each ScenePresence against the filter
750 ForEachScenePresence(delegate(ScenePresence presence)
751 { 739 {
752 if (filter(presence)) 740 if (presence.Firstname == firstName && presence.Lastname == lastName)
753 result.Add(presence); 741 return presence;
754 }); 742 }
755 return result; 743 return null;
756 } 744 }
757 745
758 /// <summary> 746 /// <summary>
759 /// Request the ScenePresence in this region matching filter. 747 /// Request the scene presence by localID.
760 /// Only the first match is returned.
761 ///
762 /// </summary> 748 /// </summary>
763 /// <param name="filter"></param> 749 /// <param name="localID"></param>
764 /// <returns></returns> 750 /// <returns>null if the presence was not found</returns>
765 protected internal ScenePresence GetScenePresence(FilterAvatarList filter) 751 protected internal ScenePresence GetScenePresence(uint localID)
766 { 752 {
767 ScenePresence result = null; 753 foreach (ScenePresence presence in GetScenePresences())
768 // Get all of the ScenePresences 754 if (presence.LocalId == localID)
769 List<ScenePresence> presences = GetScenePresences(); 755 return presence;
770 foreach (ScenePresence presence in presences) 756 return null;
771 {
772 if (filter(presence))
773 {
774 result = presence;
775 break;
776 }
777 }
778 return result;
779 } 757 }
780 758
781 protected internal ScenePresence GetScenePresence(string firstName, string lastName) 759 protected internal bool TryGetAvatar(UUID agentID, out ScenePresence avatar)
782 { 760 {
783 return GetScenePresence(delegate(ScenePresence presence) 761 lock (m_scenePresences)
784 { 762 {
785 return(presence.Firstname == firstName && presence.Lastname == lastName); 763 m_scenePresences.TryGetValue(agentID, out avatar);
786 }); 764 }
787 } 765 return (avatar != null);
788
789 /// <summary>
790 /// Request a scene presence by UUID
791 /// </summary>
792 /// <param name="agentID"></param>
793 /// <returns>null if the agent was not found</returns>
794 protected internal ScenePresence GetScenePresence(UUID agentID)
795 {
796 ScenePresence sp;
797 TryGetAvatar(agentID, out sp);
798 return sp;
799 } 766 }
800 767
801 /// <summary> 768 protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar)
802 /// Request the ScenePresence in this region by localID.
803 /// </summary>
804 /// <param name="localID"></param>
805 /// <returns></returns>
806 protected internal ScenePresence GetScenePresence(uint localID)
807 { 769 {
808 return GetScenePresence(delegate(ScenePresence presence) 770 avatar = null;
771 foreach (ScenePresence presence in GetScenePresences())
809 { 772 {
810 return (presence.LocalId == localID); 773 if (String.Compare(name, presence.ControllingClient.Name, true) == 0)
811 }); 774 {
775 avatar = presence;
776 break;
777 }
778 }
779 return (avatar != null);
812 } 780 }
813 781
814 /// <summary> 782 /// <summary>
@@ -962,24 +930,6 @@ namespace OpenSim.Region.Framework.Scenes
962 return group.GetChildPart(fullID); 930 return group.GetChildPart(fullID);
963 } 931 }
964 932
965 protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
966 {
967 lock (m_scenePresences)
968 {
969 m_scenePresences.TryGetValue(avatarId, out avatar);
970 }
971 return (avatar != null);
972 }
973
974 protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
975 {
976 avatar = GetScenePresence(delegate(ScenePresence presence)
977 {
978 return (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0);
979 });
980 return (avatar != null);
981 }
982
983 /// <summary> 933 /// <summary>
984 /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over 934 /// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over
985 /// it 935 /// it
@@ -1042,6 +992,10 @@ namespace OpenSim.Region.Framework.Scenes
1042 return UUID.Zero; 992 return UUID.Zero;
1043 } 993 }
1044 994
995 /// <summary>
996 /// Performs action on all scene object groups.
997 /// </summary>
998 /// <param name="action"></param>
1045 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 999 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1046 { 1000 {
1047 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); 1001 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
@@ -1061,23 +1015,41 @@ namespace OpenSim.Region.Framework.Scenes
1061 1015
1062 1016
1063 /// <summary> 1017 /// <summary>
1064 /// Performs action on all scene presences. 1018 /// Performs action on all scene presences. This can ultimately run the actions in parallel but
1019 /// any delegates passed in will need to implement their own locking on data they reference and
1020 /// modify outside of the scope of the delegate.
1065 /// </summary> 1021 /// </summary>
1066 /// <param name="action"></param> 1022 /// <param name="action"></param>
1067 public void ForEachScenePresence(Action<ScenePresence> action) 1023 public void ForEachScenePresence(Action<ScenePresence> action)
1068 { 1024 {
1069 List<ScenePresence> presences = GetScenePresences(); 1025 // Once all callers have their delegates configured for parallelism, we can unleash this
1070 try 1026 /*
1027 Action<ScenePresence> protectedAction = new Action<ScenePresence>(delegate(ScenePresence sp)
1028 {
1029 try
1030 {
1031 action(sp);
1032 }
1033 catch (Exception e)
1034 {
1035 m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
1036 m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
1037 }
1038 });
1039 Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction);
1040 */
1041 // For now, perform actiona serially
1042 foreach (ScenePresence sp in GetScenePresences())
1071 { 1043 {
1072 foreach(ScenePresence presence in presences) 1044 try
1073 { 1045 {
1074 action(presence); 1046 action(sp);
1047 }
1048 catch (Exception e)
1049 {
1050 m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
1051 m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
1075 } 1052 }
1076 }
1077 catch (Exception e)
1078 {
1079 m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
1080 m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
1081 } 1053 }
1082 } 1054 }
1083 1055
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index a955532..1168341 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -454,8 +454,10 @@ namespace OpenSim.Region.Framework.Scenes
454 454
455 ForEachCurrentScene(delegate(Scene scene) 455 ForEachCurrentScene(delegate(Scene scene)
456 { 456 {
457 List<ScenePresence> scenePresences = scene.GetScenePresences(); 457 scene.ForEachScenePresence(delegate(ScenePresence sp)
458 presences.AddRange(scenePresences); 458 {
459 presences.Add(sp);
460 });
459 }); 461 });
460 462
461 return presences; 463 return presences;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 0e21487..88bdf31 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1321,11 +1321,11 @@ namespace OpenSim.Region.Framework.Scenes
1321 if (volume < 0) 1321 if (volume < 0)
1322 volume = 0; 1322 volume = 0;
1323 1323
1324 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 1324 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence sp)
1325 foreach (ScenePresence p in avatarts)
1326 { 1325 {
1327 p.ControllingClient.SendAttachedSoundGainChange(UUID, (float)volume); 1326 if(!sp.IsChildAgent)
1328 } 1327 sp.ControllingClient.SendAttachedSoundGainChange(UUID, (float)volume);
1328 });
1329 } 1329 }
1330 1330
1331 /// <summary> 1331 /// <summary>
@@ -2609,12 +2609,13 @@ namespace OpenSim.Region.Framework.Scenes
2609 } 2609 }
2610 } 2610 }
2611 2611
2612 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 2612 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence sp)
2613 foreach (ScenePresence p in avatarts)
2614 { 2613 {
2615 if (!(Util.GetDistanceTo(p.AbsolutePosition, AbsolutePosition) >= 100)) 2614 if (sp.IsChildAgent)
2616 p.ControllingClient.SendPreLoadSound(objectID, objectID, soundID); 2615 return;
2617 } 2616 if (!(Util.GetDistanceTo(sp.AbsolutePosition, AbsolutePosition) >= 100))
2617 sp.ControllingClient.SendPreLoadSound(objectID, objectID, soundID);
2618 });
2618 } 2619 }
2619 2620
2620 public void RemFlag(PrimFlags flag) 2621 public void RemFlag(PrimFlags flag)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 766f6d3..b5f6217 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2396,35 +2396,33 @@ namespace OpenSim.Region.Framework.Scenes
2396 2396
2397 List<Vector3> CoarseLocations = new List<Vector3>(); 2397 List<Vector3> CoarseLocations = new List<Vector3>();
2398 List<UUID> AvatarUUIDs = new List<UUID>(); 2398 List<UUID> AvatarUUIDs = new List<UUID>();
2399 List<ScenePresence> avatars = m_scene.GetAvatars(); 2399 m_scene.ForEachScenePresence(delegate(ScenePresence sp)
2400 for (int i = 0; i < avatars.Count; i++)
2401 { 2400 {
2402 // Requested by LibOMV. Send Course Location on self. 2401 if (sp.IsChildAgent)
2403 //if (avatars[i] != this) 2402 return;
2404 //{ 2403
2405 if (avatars[i].ParentID != 0) 2404 if (sp.ParentID != 0)
2405 {
2406 // sitting avatar
2407 SceneObjectPart sop = m_scene.GetSceneObjectPart(sp.ParentID);
2408 if (sop != null)
2406 { 2409 {
2407 // sitting avatar 2410 CoarseLocations.Add(sop.AbsolutePosition + sp.m_pos);
2408 SceneObjectPart sop = m_scene.GetSceneObjectPart(avatars[i].ParentID); 2411 AvatarUUIDs.Add(sp.UUID);
2409 if (sop != null)
2410 {
2411 CoarseLocations.Add(sop.AbsolutePosition + avatars[i].m_pos);
2412 AvatarUUIDs.Add(avatars[i].UUID);
2413 }
2414 else
2415 {
2416 // we can't find the parent.. ! arg!
2417 CoarseLocations.Add(avatars[i].m_pos);
2418 AvatarUUIDs.Add(avatars[i].UUID);
2419 }
2420 } 2412 }
2421 else 2413 else
2422 { 2414 {
2423 CoarseLocations.Add(avatars[i].m_pos); 2415 // we can't find the parent.. ! arg!
2424 AvatarUUIDs.Add(avatars[i].UUID); 2416 CoarseLocations.Add(sp.m_pos);
2417 AvatarUUIDs.Add(sp.UUID);
2425 } 2418 }
2426 //} 2419 }
2427 } 2420 else
2421 {
2422 CoarseLocations.Add(sp.m_pos);
2423 AvatarUUIDs.Add(sp.UUID);
2424 }
2425 });
2428 2426
2429 m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations); 2427 m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations);
2430 2428
@@ -2498,13 +2496,15 @@ namespace OpenSim.Region.Framework.Scenes
2498 m_perfMonMS = Util.EnvironmentTickCount(); 2496 m_perfMonMS = Util.EnvironmentTickCount();
2499 2497
2500 // only send update from root agents to other clients; children are only "listening posts" 2498 // only send update from root agents to other clients; children are only "listening posts"
2501 List<ScenePresence> avatars = m_scene.GetAvatars(); 2499 int count = 0;
2502 foreach (ScenePresence avatar in avatars) 2500 m_scene.ForEachScenePresence(delegate(ScenePresence sp)
2503 { 2501 {
2504 SendFullUpdateToOtherClient(avatar); 2502 if (sp.IsChildAgent)
2505 2503 return;
2506 } 2504 SendFullUpdateToOtherClient(sp);
2507 m_scene.StatsReporter.AddAgentUpdates(avatars.Count); 2505 ++count;
2506 });
2507 m_scene.StatsReporter.AddAgentUpdates(count);
2508 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2508 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2509 2509
2510 Animator.SendAnimPack(); 2510 Animator.SendAnimPack();