diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 9306ace1e6..7263b5107b 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -352,7 +352,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // the avatar.Close below will clear the child region list. We need this below for (possibly) // closing the child agents, so save it here (we need a copy as it is Clear()-ed). - //List childRegions = new List(avatar.GetKnownRegionList()); + //List childRegions = avatar.KnownRegionHandles; // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport // failure at this point (unlike a border crossing failure). So perhaps this can never fail // once we reach here... diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index cd4b14d27f..a432b6fe14 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1135,9 +1135,8 @@ namespace OpenSim.Region.Framework.Scenes // Kick all ROOT agents with the message, 'The simulator is going down' ForEachScenePresence(delegate(ScenePresence avatar) - { - if (avatar.KnownChildRegionHandles.Contains(RegionInfo.RegionHandle)) - avatar.KnownChildRegionHandles.Remove(RegionInfo.RegionHandle); + { + avatar.RemoveNeighbourRegion(RegionInfo.RegionHandle); if (!avatar.IsChildAgent) avatar.ControllingClient.Kick("The simulator is going down."); @@ -3225,14 +3224,8 @@ namespace OpenSim.Region.Framework.Scenes avatar.Scene.NeedSceneCacheClear(avatar.UUID); if (closeChildAgents && !avatar.IsChildAgent) - { - //List childknownRegions = new List(); - //List ckn = avatar.KnownChildRegionHandles; - //for (int i = 0; i < ckn.Count; i++) - //{ - // childknownRegions.Add(ckn[i]); - //} - List regions = new List(avatar.KnownChildRegionHandles); + { + List regions = avatar.KnownRegionHandles; regions.Remove(RegionInfo.RegionHandle); m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); } @@ -3313,7 +3306,7 @@ namespace OpenSim.Region.Framework.Scenes { for (int i = 0; i < regionslst.Count; i++) { - av.KnownChildRegionHandles.Remove(regionslst[i]); + av.RemoveNeighbourRegion(regionslst[i]); } } } @@ -3827,7 +3820,7 @@ namespace OpenSim.Region.Framework.Scenes if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret)) { - m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, new List(loggingOffUser.KnownRegions.Keys)); + m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles); loggingOffUser.ControllingClient.Kick(message); // Give them a second to receive the message! Thread.Sleep(1000); diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 19cb0c16ba..fe9fe31962 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -225,7 +225,7 @@ namespace OpenSim.Region.Framework.Scenes { uint x = 0, y = 0; List simulatorList = new List(); - foreach (ulong regionHandle in presence.KnownChildRegionHandles) + foreach (ulong regionHandle in presence.KnownRegionHandles) { if (regionHandle != m_regionInfo.RegionHandle) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 925a4f3e7e..9e04aa145b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -243,11 +243,6 @@ namespace OpenSim.Region.Framework.Scenes } } - - // neighbouring regions we have enabled a child agent in - // holds the seed cap for the child agent in that region - private Dictionary m_knownChildRegions = new Dictionary(); - /// /// Copy of the script states while the agent is in transit. This state may /// need to be placed back in case of transfer fail. @@ -699,29 +694,6 @@ namespace OpenSim.Region.Framework.Scenes set { m_health = value; } } - /// - /// These are the region handles known by the avatar. - /// - public List KnownChildRegionHandles - { - get - { - if (m_knownChildRegions.Count == 0) - return new List(); - else - return new List(m_knownChildRegions.Keys); - } - } - - public Dictionary KnownRegions - { - get { return m_knownChildRegions; } - set - { - m_knownChildRegions = value; - } - } - private ISceneViewer m_sceneViewer; public ISceneViewer SceneViewer @@ -1253,7 +1225,11 @@ namespace OpenSim.Region.Framework.Scenes public void StopFlying() { ControllingClient.StopFlying(this); - } + } + + // neighbouring regions we have enabled a child agent in + // holds the seed cap for the child agent in that region + private Dictionary m_knownChildRegions = new Dictionary(); public void AddNeighbourRegion(ulong regionHandle, string cap) { @@ -1269,14 +1245,14 @@ namespace OpenSim.Region.Framework.Scenes } public void RemoveNeighbourRegion(ulong regionHandle) - { + { lock (m_knownChildRegions) { - if (m_knownChildRegions.ContainsKey(regionHandle)) - { - m_knownChildRegions.Remove(regionHandle); - //m_log.Debug(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); - } + // Checking ContainsKey is redundant as Remove works either way and returns a bool + // This is here to allow the Debug output to be conditional on removal + //if (m_knownChildRegions.ContainsKey(regionHandle)) + // m_log.DebugFormat(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); + m_knownChildRegions.Remove(regionHandle); } } @@ -1287,11 +1263,39 @@ namespace OpenSim.Region.Framework.Scenes RemoveNeighbourRegion(handle); Scene.CapsModule.DropChildSeed(UUID, handle); } - } - - public List GetKnownRegionList() - { - return new List(m_knownChildRegions.Keys); + } + + public Dictionary KnownRegions + { + get + { + lock (m_knownChildRegions) + return new Dictionary(m_knownChildRegions); + } + set + { + // Replacing the reference is atomic but we still need to lock on + // the original dictionary object which may be in use elsewhere + lock (m_knownChildRegions) + m_knownChildRegions = value; + } + } + + public List KnownRegionHandles + { + get + { + return new List(KnownRegions.Keys); + } + } + + public int KnownRegionCount + { + get + { + lock (m_knownChildRegions) + return m_knownChildRegions.Count; + } } #endregion @@ -3082,7 +3086,7 @@ namespace OpenSim.Region.Framework.Scenes // Throttles float multiplier = 1; - int childRegions = m_knownChildRegions.Count; + int childRegions = KnownRegionCount; if (childRegions != 0) multiplier = 1f / childRegions; @@ -3334,30 +3338,28 @@ namespace OpenSim.Region.Framework.Scenes /// public void CloseChildAgents(uint newRegionX, uint newRegionY) { - List byebyeRegions = new List(); + List byebyeRegions = new List(); + List knownRegions = KnownRegionHandles; m_log.DebugFormat( "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}", - m_knownChildRegions.Keys.Count, Scene.RegionInfo.RegionName); - //DumpKnownRegions(); - - lock (m_knownChildRegions) + knownRegions.Count, Scene.RegionInfo.RegionName); + //DumpKnownRegions(); + + foreach (ulong handle in knownRegions) { - foreach (ulong handle in m_knownChildRegions.Keys) + // Don't close the agent on this region yet + if (handle != Scene.RegionInfo.RegionHandle) { - // Don't close the agent on this region yet - if (handle != Scene.RegionInfo.RegionHandle) - { - uint x, y; - Utils.LongToUInts(handle, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; + uint x, y; + Utils.LongToUInts(handle, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; - //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); - //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); - if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) - { - byebyeRegions.Add(handle); - } + //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); + //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); + if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) + { + byebyeRegions.Add(handle); } } } @@ -3475,7 +3477,7 @@ namespace OpenSim.Region.Framework.Scenes // Throttles float multiplier = 1; - int childRegions = m_knownChildRegions.Count; + int childRegions = KnownRegionCount; if (childRegions != 0) multiplier = 1f / childRegions; @@ -3939,12 +3941,10 @@ namespace OpenSim.Region.Framework.Scenes public void Close() { if (!IsChildAgent) - m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); - - lock (m_knownChildRegions) - { - m_knownChildRegions.Clear(); - } + m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); + + // Clear known regions + KnownRegions = new Dictionary(); lock (m_reprioritization_timer) { diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index ce9d418d15..119eb1f253 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 string cap = presence.ControllingClient.RequestClientInfo().CapsPath; presence.AddNeighbourRegion(region2, cap); - presence.AddNeighbourRegion(region3, cap); - - List neighbours = presence.GetKnownRegionList(); - - Assert.That(neighbours.Count, Is.EqualTo(2)); + presence.AddNeighbourRegion(region3, cap); + + Assert.That(presence.KnownRegionCount, Is.EqualTo(2)); } [Test] @@ -230,8 +228,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests ScenePresence presence = scene.GetScenePresence(agent1); presence.RemoveNeighbourRegion(region3); - List neighbours = presence.GetKnownRegionList(); - Assert.That(neighbours.Count,Is.EqualTo(1)); + Assert.That(presence.KnownRegionCount,Is.EqualTo(1)); /* presence.MakeChildAgent; presence.MakeRootAgent;