aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDan Lake2011-10-06 22:47:33 -0700
committerDan Lake2011-10-06 22:47:33 -0700
commit4748c19bdbcdcaf6050e1f04a5f7394a88e0bf3e (patch)
treedc2b8f85bebe216378d54dab9410f0a8805145cf
parentMerge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff)
downloadopensim-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.
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs134
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs11
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;