From 4748c19bdbcdcaf6050e1f04a5f7394a88e0bf3e Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Thu, 6 Oct 2011 22:47:33 -0700 Subject: 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. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 134 +++++++++++------------ 1 file changed, 67 insertions(+), 67 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs') 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 } } - - // 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. @@ -635,29 +630,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 @@ -1103,7 +1075,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) { @@ -1119,14 +1095,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); } } @@ -1137,11 +1113,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 @@ -2730,7 +2734,7 @@ namespace OpenSim.Region.Framework.Scenes // Throttles float multiplier = 1; - int childRegions = m_knownChildRegions.Count; + int childRegions = KnownRegionCount; if (childRegions != 0) multiplier = 1f / childRegions; @@ -2982,30 +2986,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; + + //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)) { - 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); - } + byebyeRegions.Add(handle); } } } @@ -3123,7 +3125,7 @@ namespace OpenSim.Region.Framework.Scenes // Throttles float multiplier = 1; - int childRegions = m_knownChildRegions.Count; + int childRegions = KnownRegionCount; if (childRegions != 0) multiplier = 1f / childRegions; @@ -3432,12 +3434,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) { -- cgit v1.1