diff options
author | Dan Lake | 2011-10-06 22:47:33 -0700 |
---|---|---|
committer | Dan Lake | 2011-10-06 22:47:33 -0700 |
commit | 4748c19bdbcdcaf6050e1f04a5f7394a88e0bf3e (patch) | |
tree | dc2b8f85bebe216378d54dab9410f0a8805145cf /OpenSim | |
parent | Merge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff) | |
download | opensim-SC-4748c19bdbcdcaf6050e1f04a5f7394a88e0bf3e.zip opensim-SC-4748c19bdbcdcaf6050e1f04a5f7394a88e0bf3e.tar.gz opensim-SC-4748c19bdbcdcaf6050e1f04a5f7394a88e0bf3e.tar.bz2 opensim-SC-4748c19bdbcdcaf6050e1f04a5f7394a88e0bf3e.tar.xz |
Refactored "known child region" in ScenePresence. There were 4 different
ways to access the list/dictionary of child regions and locking was
inconsistent. There are now public properties which enforce locks.
Callers are no longer required to create new copies of lists.
Diffstat (limited to 'OpenSim')
5 files changed, 79 insertions, 89 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 083ee33..f4d2fda 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -351,7 +351,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
351 | 351 | ||
352 | // the avatar.Close below will clear the child region list. We need this below for (possibly) | 352 | // the avatar.Close below will clear the child region list. We need this below for (possibly) |
353 | // closing the child agents, so save it here (we need a copy as it is Clear()-ed). | 353 | // closing the child agents, so save it here (we need a copy as it is Clear()-ed). |
354 | //List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList()); | 354 | //List<ulong> childRegions = avatar.KnownRegionHandles; |
355 | // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport | 355 | // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport |
356 | // failure at this point (unlike a border crossing failure). So perhaps this can never fail | 356 | // failure at this point (unlike a border crossing failure). So perhaps this can never fail |
357 | // once we reach here... | 357 | // once we reach here... |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b1755ac..992e6c5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1109,9 +1109,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1109 | 1109 | ||
1110 | // Kick all ROOT agents with the message, 'The simulator is going down' | 1110 | // Kick all ROOT agents with the message, 'The simulator is going down' |
1111 | ForEachScenePresence(delegate(ScenePresence avatar) | 1111 | ForEachScenePresence(delegate(ScenePresence avatar) |
1112 | { | 1112 | { |
1113 | if (avatar.KnownChildRegionHandles.Contains(RegionInfo.RegionHandle)) | 1113 | avatar.RemoveNeighbourRegion(RegionInfo.RegionHandle); |
1114 | avatar.KnownChildRegionHandles.Remove(RegionInfo.RegionHandle); | ||
1115 | 1114 | ||
1116 | if (!avatar.IsChildAgent) | 1115 | if (!avatar.IsChildAgent) |
1117 | avatar.ControllingClient.Kick("The simulator is going down."); | 1116 | avatar.ControllingClient.Kick("The simulator is going down."); |
@@ -3103,14 +3102,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3103 | avatar.Scene.NeedSceneCacheClear(avatar.UUID); | 3102 | avatar.Scene.NeedSceneCacheClear(avatar.UUID); |
3104 | 3103 | ||
3105 | if (closeChildAgents && !avatar.IsChildAgent) | 3104 | if (closeChildAgents && !avatar.IsChildAgent) |
3106 | { | 3105 | { |
3107 | //List<ulong> childknownRegions = new List<ulong>(); | 3106 | List<ulong> regions = avatar.KnownRegionHandles; |
3108 | //List<ulong> ckn = avatar.KnownChildRegionHandles; | ||
3109 | //for (int i = 0; i < ckn.Count; i++) | ||
3110 | //{ | ||
3111 | // childknownRegions.Add(ckn[i]); | ||
3112 | //} | ||
3113 | List<ulong> regions = new List<ulong>(avatar.KnownChildRegionHandles); | ||
3114 | regions.Remove(RegionInfo.RegionHandle); | 3107 | regions.Remove(RegionInfo.RegionHandle); |
3115 | m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); | 3108 | m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); |
3116 | } | 3109 | } |
@@ -3181,7 +3174,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3181 | { | 3174 | { |
3182 | for (int i = 0; i < regionslst.Count; i++) | 3175 | for (int i = 0; i < regionslst.Count; i++) |
3183 | { | 3176 | { |
3184 | av.KnownChildRegionHandles.Remove(regionslst[i]); | 3177 | av.RemoveNeighbourRegion(regionslst[i]); |
3185 | } | 3178 | } |
3186 | } | 3179 | } |
3187 | } | 3180 | } |
@@ -3674,7 +3667,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3674 | 3667 | ||
3675 | if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret)) | 3668 | if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret)) |
3676 | { | 3669 | { |
3677 | m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, new List<ulong>(loggingOffUser.KnownRegions.Keys)); | 3670 | m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles); |
3678 | loggingOffUser.ControllingClient.Kick(message); | 3671 | loggingOffUser.ControllingClient.Kick(message); |
3679 | // Give them a second to receive the message! | 3672 | // Give them a second to receive the message! |
3680 | Thread.Sleep(1000); | 3673 | Thread.Sleep(1000); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 837e655..7cffa70 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | |||
@@ -229,7 +229,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
229 | { | 229 | { |
230 | uint x = 0, y = 0; | 230 | uint x = 0, y = 0; |
231 | List<string> simulatorList = new List<string>(); | 231 | List<string> simulatorList = new List<string>(); |
232 | foreach (ulong regionHandle in presence.KnownChildRegionHandles) | 232 | foreach (ulong regionHandle in presence.KnownRegionHandles) |
233 | { | 233 | { |
234 | if (regionHandle != m_regionInfo.RegionHandle) | 234 | if (regionHandle != m_regionInfo.RegionHandle) |
235 | { | 235 | { |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e4e5f17..e7ef377 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -219,11 +219,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | |||
223 | // neighbouring regions we have enabled a child agent in | ||
224 | // holds the seed cap for the child agent in that region | ||
225 | private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>(); | ||
226 | |||
227 | /// <summary> | 222 | /// <summary> |
228 | /// Copy of the script states while the agent is in transit. This state may | 223 | /// Copy of the script states while the agent is in transit. This state may |
229 | /// need to be placed back in case of transfer fail. | 224 | /// need to be placed back in case of transfer fail. |
@@ -635,29 +630,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
635 | set { m_health = value; } | 630 | set { m_health = value; } |
636 | } | 631 | } |
637 | 632 | ||
638 | /// <summary> | ||
639 | /// These are the region handles known by the avatar. | ||
640 | /// </summary> | ||
641 | public List<ulong> KnownChildRegionHandles | ||
642 | { | ||
643 | get | ||
644 | { | ||
645 | if (m_knownChildRegions.Count == 0) | ||
646 | return new List<ulong>(); | ||
647 | else | ||
648 | return new List<ulong>(m_knownChildRegions.Keys); | ||
649 | } | ||
650 | } | ||
651 | |||
652 | public Dictionary<ulong, string> KnownRegions | ||
653 | { | ||
654 | get { return m_knownChildRegions; } | ||
655 | set | ||
656 | { | ||
657 | m_knownChildRegions = value; | ||
658 | } | ||
659 | } | ||
660 | |||
661 | private ISceneViewer m_sceneViewer; | 633 | private ISceneViewer m_sceneViewer; |
662 | 634 | ||
663 | public ISceneViewer SceneViewer | 635 | public ISceneViewer SceneViewer |
@@ -1103,7 +1075,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1103 | public void StopFlying() | 1075 | public void StopFlying() |
1104 | { | 1076 | { |
1105 | ControllingClient.StopFlying(this); | 1077 | ControllingClient.StopFlying(this); |
1106 | } | 1078 | } |
1079 | |||
1080 | // neighbouring regions we have enabled a child agent in | ||
1081 | // holds the seed cap for the child agent in that region | ||
1082 | private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>(); | ||
1107 | 1083 | ||
1108 | public void AddNeighbourRegion(ulong regionHandle, string cap) | 1084 | public void AddNeighbourRegion(ulong regionHandle, string cap) |
1109 | { | 1085 | { |
@@ -1119,14 +1095,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1119 | } | 1095 | } |
1120 | 1096 | ||
1121 | public void RemoveNeighbourRegion(ulong regionHandle) | 1097 | public void RemoveNeighbourRegion(ulong regionHandle) |
1122 | { | 1098 | { |
1123 | lock (m_knownChildRegions) | 1099 | lock (m_knownChildRegions) |
1124 | { | 1100 | { |
1125 | if (m_knownChildRegions.ContainsKey(regionHandle)) | 1101 | // Checking ContainsKey is redundant as Remove works either way and returns a bool |
1126 | { | 1102 | // This is here to allow the Debug output to be conditional on removal |
1127 | m_knownChildRegions.Remove(regionHandle); | 1103 | //if (m_knownChildRegions.ContainsKey(regionHandle)) |
1128 | //m_log.Debug(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); | 1104 | // m_log.DebugFormat(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); |
1129 | } | 1105 | m_knownChildRegions.Remove(regionHandle); |
1130 | } | 1106 | } |
1131 | } | 1107 | } |
1132 | 1108 | ||
@@ -1137,11 +1113,39 @@ namespace OpenSim.Region.Framework.Scenes | |||
1137 | RemoveNeighbourRegion(handle); | 1113 | RemoveNeighbourRegion(handle); |
1138 | Scene.CapsModule.DropChildSeed(UUID, handle); | 1114 | Scene.CapsModule.DropChildSeed(UUID, handle); |
1139 | } | 1115 | } |
1140 | } | 1116 | } |
1141 | 1117 | ||
1142 | public List<ulong> GetKnownRegionList() | 1118 | public Dictionary<ulong, string> KnownRegions |
1143 | { | 1119 | { |
1144 | return new List<ulong>(m_knownChildRegions.Keys); | 1120 | get |
1121 | { | ||
1122 | lock (m_knownChildRegions) | ||
1123 | return new Dictionary<ulong, string>(m_knownChildRegions); | ||
1124 | } | ||
1125 | set | ||
1126 | { | ||
1127 | // Replacing the reference is atomic but we still need to lock on | ||
1128 | // the original dictionary object which may be in use elsewhere | ||
1129 | lock (m_knownChildRegions) | ||
1130 | m_knownChildRegions = value; | ||
1131 | } | ||
1132 | } | ||
1133 | |||
1134 | public List<ulong> KnownRegionHandles | ||
1135 | { | ||
1136 | get | ||
1137 | { | ||
1138 | return new List<ulong>(KnownRegions.Keys); | ||
1139 | } | ||
1140 | } | ||
1141 | |||
1142 | public int KnownRegionCount | ||
1143 | { | ||
1144 | get | ||
1145 | { | ||
1146 | lock (m_knownChildRegions) | ||
1147 | return m_knownChildRegions.Count; | ||
1148 | } | ||
1145 | } | 1149 | } |
1146 | 1150 | ||
1147 | #endregion | 1151 | #endregion |
@@ -2730,7 +2734,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2730 | 2734 | ||
2731 | // Throttles | 2735 | // Throttles |
2732 | float multiplier = 1; | 2736 | float multiplier = 1; |
2733 | int childRegions = m_knownChildRegions.Count; | 2737 | int childRegions = KnownRegionCount; |
2734 | if (childRegions != 0) | 2738 | if (childRegions != 0) |
2735 | multiplier = 1f / childRegions; | 2739 | multiplier = 1f / childRegions; |
2736 | 2740 | ||
@@ -2982,30 +2986,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
2982 | /// <returns></returns> | 2986 | /// <returns></returns> |
2983 | public void CloseChildAgents(uint newRegionX, uint newRegionY) | 2987 | public void CloseChildAgents(uint newRegionX, uint newRegionY) |
2984 | { | 2988 | { |
2985 | List<ulong> byebyeRegions = new List<ulong>(); | 2989 | List<ulong> byebyeRegions = new List<ulong>(); |
2990 | List<ulong> knownRegions = KnownRegionHandles; | ||
2986 | m_log.DebugFormat( | 2991 | m_log.DebugFormat( |
2987 | "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}", | 2992 | "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}", |
2988 | m_knownChildRegions.Keys.Count, Scene.RegionInfo.RegionName); | 2993 | knownRegions.Count, Scene.RegionInfo.RegionName); |
2989 | //DumpKnownRegions(); | 2994 | //DumpKnownRegions(); |
2990 | 2995 | ||
2991 | lock (m_knownChildRegions) | 2996 | foreach (ulong handle in knownRegions) |
2992 | { | 2997 | { |
2993 | foreach (ulong handle in m_knownChildRegions.Keys) | 2998 | // Don't close the agent on this region yet |
2999 | if (handle != Scene.RegionInfo.RegionHandle) | ||
2994 | { | 3000 | { |
2995 | // Don't close the agent on this region yet | 3001 | uint x, y; |
2996 | if (handle != Scene.RegionInfo.RegionHandle) | 3002 | Utils.LongToUInts(handle, out x, out y); |
3003 | x = x / Constants.RegionSize; | ||
3004 | y = y / Constants.RegionSize; | ||
3005 | |||
3006 | //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); | ||
3007 | //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); | ||
3008 | if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) | ||
2997 | { | 3009 | { |
2998 | uint x, y; | 3010 | byebyeRegions.Add(handle); |
2999 | Utils.LongToUInts(handle, out x, out y); | ||
3000 | x = x / Constants.RegionSize; | ||
3001 | y = y / Constants.RegionSize; | ||
3002 | |||
3003 | //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); | ||
3004 | //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); | ||
3005 | if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) | ||
3006 | { | ||
3007 | byebyeRegions.Add(handle); | ||
3008 | } | ||
3009 | } | 3011 | } |
3010 | } | 3012 | } |
3011 | } | 3013 | } |
@@ -3123,7 +3125,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3123 | 3125 | ||
3124 | // Throttles | 3126 | // Throttles |
3125 | float multiplier = 1; | 3127 | float multiplier = 1; |
3126 | int childRegions = m_knownChildRegions.Count; | 3128 | int childRegions = KnownRegionCount; |
3127 | if (childRegions != 0) | 3129 | if (childRegions != 0) |
3128 | multiplier = 1f / childRegions; | 3130 | multiplier = 1f / childRegions; |
3129 | 3131 | ||
@@ -3432,12 +3434,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3432 | public void Close() | 3434 | public void Close() |
3433 | { | 3435 | { |
3434 | if (!IsChildAgent) | 3436 | if (!IsChildAgent) |
3435 | m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); | 3437 | m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); |
3436 | 3438 | ||
3437 | lock (m_knownChildRegions) | 3439 | // Clear known regions |
3438 | { | 3440 | KnownRegions = new Dictionary<ulong, string>(); |
3439 | m_knownChildRegions.Clear(); | ||
3440 | } | ||
3441 | 3441 | ||
3442 | lock (m_reprioritization_timer) | 3442 | lock (m_reprioritization_timer) |
3443 | { | 3443 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index ce9d418..119eb1f 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs | |||
@@ -215,11 +215,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
215 | string cap = presence.ControllingClient.RequestClientInfo().CapsPath; | 215 | string cap = presence.ControllingClient.RequestClientInfo().CapsPath; |
216 | 216 | ||
217 | presence.AddNeighbourRegion(region2, cap); | 217 | presence.AddNeighbourRegion(region2, cap); |
218 | presence.AddNeighbourRegion(region3, cap); | 218 | presence.AddNeighbourRegion(region3, cap); |
219 | 219 | ||
220 | List<ulong> neighbours = presence.GetKnownRegionList(); | 220 | Assert.That(presence.KnownRegionCount, Is.EqualTo(2)); |
221 | |||
222 | Assert.That(neighbours.Count, Is.EqualTo(2)); | ||
223 | } | 221 | } |
224 | 222 | ||
225 | [Test] | 223 | [Test] |
@@ -230,8 +228,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
230 | ScenePresence presence = scene.GetScenePresence(agent1); | 228 | ScenePresence presence = scene.GetScenePresence(agent1); |
231 | presence.RemoveNeighbourRegion(region3); | 229 | presence.RemoveNeighbourRegion(region3); |
232 | 230 | ||
233 | List<ulong> neighbours = presence.GetKnownRegionList(); | 231 | Assert.That(presence.KnownRegionCount,Is.EqualTo(1)); |
234 | Assert.That(neighbours.Count,Is.EqualTo(1)); | ||
235 | /* | 232 | /* |
236 | presence.MakeChildAgent; | 233 | presence.MakeChildAgent; |
237 | presence.MakeRootAgent; | 234 | presence.MakeRootAgent; |