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.remove-scene-viewer
parent
4c812884be
commit
4748c19bdb
|
@ -351,7 +351,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
// the avatar.Close below will clear the child region list. We need this below for (possibly)
|
// 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).
|
// closing the child agents, so save it here (we need a copy as it is Clear()-ed).
|
||||||
//List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList());
|
//List<ulong> childRegions = avatar.KnownRegionHandles;
|
||||||
// Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
|
// 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
|
// failure at this point (unlike a border crossing failure). So perhaps this can never fail
|
||||||
// once we reach here...
|
// once we reach here...
|
||||||
|
|
|
@ -1109,9 +1109,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// Kick all ROOT agents with the message, 'The simulator is going down'
|
// Kick all ROOT agents with the message, 'The simulator is going down'
|
||||||
ForEachScenePresence(delegate(ScenePresence avatar)
|
ForEachScenePresence(delegate(ScenePresence avatar)
|
||||||
{
|
{
|
||||||
if (avatar.KnownChildRegionHandles.Contains(RegionInfo.RegionHandle))
|
avatar.RemoveNeighbourRegion(RegionInfo.RegionHandle);
|
||||||
avatar.KnownChildRegionHandles.Remove(RegionInfo.RegionHandle);
|
|
||||||
|
|
||||||
if (!avatar.IsChildAgent)
|
if (!avatar.IsChildAgent)
|
||||||
avatar.ControllingClient.Kick("The simulator is going down.");
|
avatar.ControllingClient.Kick("The simulator is going down.");
|
||||||
|
@ -3103,14 +3102,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
avatar.Scene.NeedSceneCacheClear(avatar.UUID);
|
avatar.Scene.NeedSceneCacheClear(avatar.UUID);
|
||||||
|
|
||||||
if (closeChildAgents && !avatar.IsChildAgent)
|
if (closeChildAgents && !avatar.IsChildAgent)
|
||||||
{
|
{
|
||||||
//List<ulong> childknownRegions = new List<ulong>();
|
List<ulong> regions = avatar.KnownRegionHandles;
|
||||||
//List<ulong> ckn = avatar.KnownChildRegionHandles;
|
|
||||||
//for (int i = 0; i < ckn.Count; i++)
|
|
||||||
//{
|
|
||||||
// childknownRegions.Add(ckn[i]);
|
|
||||||
//}
|
|
||||||
List<ulong> regions = new List<ulong>(avatar.KnownChildRegionHandles);
|
|
||||||
regions.Remove(RegionInfo.RegionHandle);
|
regions.Remove(RegionInfo.RegionHandle);
|
||||||
m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
|
m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
|
||||||
}
|
}
|
||||||
|
@ -3181,7 +3174,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
for (int i = 0; i < regionslst.Count; i++)
|
for (int i = 0; i < regionslst.Count; i++)
|
||||||
{
|
{
|
||||||
av.KnownChildRegionHandles.Remove(regionslst[i]);
|
av.RemoveNeighbourRegion(regionslst[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3674,7 +3667,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret))
|
if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret))
|
||||||
{
|
{
|
||||||
m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, new List<ulong>(loggingOffUser.KnownRegions.Keys));
|
m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles);
|
||||||
loggingOffUser.ControllingClient.Kick(message);
|
loggingOffUser.ControllingClient.Kick(message);
|
||||||
// Give them a second to receive the message!
|
// Give them a second to receive the message!
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
|
|
|
@ -229,7 +229,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
uint x = 0, y = 0;
|
uint x = 0, y = 0;
|
||||||
List<string> simulatorList = new List<string>();
|
List<string> simulatorList = new List<string>();
|
||||||
foreach (ulong regionHandle in presence.KnownChildRegionHandles)
|
foreach (ulong regionHandle in presence.KnownRegionHandles)
|
||||||
{
|
{
|
||||||
if (regionHandle != m_regionInfo.RegionHandle)
|
if (regionHandle != m_regionInfo.RegionHandle)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Copy of the script states while the agent is in transit. This state may
|
/// Copy of the script states while the agent is in transit. This state may
|
||||||
/// need to be placed back in case of transfer fail.
|
/// need to be placed back in case of transfer fail.
|
||||||
|
@ -635,29 +630,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
set { m_health = value; }
|
set { m_health = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// These are the region handles known by the avatar.
|
|
||||||
/// </summary>
|
|
||||||
public List<ulong> KnownChildRegionHandles
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (m_knownChildRegions.Count == 0)
|
|
||||||
return new List<ulong>();
|
|
||||||
else
|
|
||||||
return new List<ulong>(m_knownChildRegions.Keys);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<ulong, string> KnownRegions
|
|
||||||
{
|
|
||||||
get { return m_knownChildRegions; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
m_knownChildRegions = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ISceneViewer m_sceneViewer;
|
private ISceneViewer m_sceneViewer;
|
||||||
|
|
||||||
public ISceneViewer SceneViewer
|
public ISceneViewer SceneViewer
|
||||||
|
@ -1103,7 +1075,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public void StopFlying()
|
public void StopFlying()
|
||||||
{
|
{
|
||||||
ControllingClient.StopFlying(this);
|
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<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>();
|
||||||
|
|
||||||
public void AddNeighbourRegion(ulong regionHandle, string cap)
|
public void AddNeighbourRegion(ulong regionHandle, string cap)
|
||||||
{
|
{
|
||||||
|
@ -1119,14 +1095,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveNeighbourRegion(ulong regionHandle)
|
public void RemoveNeighbourRegion(ulong regionHandle)
|
||||||
{
|
{
|
||||||
lock (m_knownChildRegions)
|
lock (m_knownChildRegions)
|
||||||
{
|
{
|
||||||
if (m_knownChildRegions.ContainsKey(regionHandle))
|
// 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
|
||||||
m_knownChildRegions.Remove(regionHandle);
|
//if (m_knownChildRegions.ContainsKey(regionHandle))
|
||||||
//m_log.Debug(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count);
|
// 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);
|
RemoveNeighbourRegion(handle);
|
||||||
Scene.CapsModule.DropChildSeed(UUID, handle);
|
Scene.CapsModule.DropChildSeed(UUID, handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ulong> GetKnownRegionList()
|
public Dictionary<ulong, string> KnownRegions
|
||||||
{
|
{
|
||||||
return new List<ulong>(m_knownChildRegions.Keys);
|
get
|
||||||
|
{
|
||||||
|
lock (m_knownChildRegions)
|
||||||
|
return new Dictionary<ulong, string>(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<ulong> KnownRegionHandles
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new List<ulong>(KnownRegions.Keys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int KnownRegionCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (m_knownChildRegions)
|
||||||
|
return m_knownChildRegions.Count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -2730,7 +2734,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// Throttles
|
// Throttles
|
||||||
float multiplier = 1;
|
float multiplier = 1;
|
||||||
int childRegions = m_knownChildRegions.Count;
|
int childRegions = KnownRegionCount;
|
||||||
if (childRegions != 0)
|
if (childRegions != 0)
|
||||||
multiplier = 1f / childRegions;
|
multiplier = 1f / childRegions;
|
||||||
|
|
||||||
|
@ -2982,30 +2986,28 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public void CloseChildAgents(uint newRegionX, uint newRegionY)
|
public void CloseChildAgents(uint newRegionX, uint newRegionY)
|
||||||
{
|
{
|
||||||
List<ulong> byebyeRegions = new List<ulong>();
|
List<ulong> byebyeRegions = new List<ulong>();
|
||||||
|
List<ulong> knownRegions = KnownRegionHandles;
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}",
|
"[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}",
|
||||||
m_knownChildRegions.Keys.Count, Scene.RegionInfo.RegionName);
|
knownRegions.Count, Scene.RegionInfo.RegionName);
|
||||||
//DumpKnownRegions();
|
//DumpKnownRegions();
|
||||||
|
|
||||||
lock (m_knownChildRegions)
|
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
|
uint x, y;
|
||||||
if (handle != Scene.RegionInfo.RegionHandle)
|
Utils.LongToUInts(handle, out x, out y);
|
||||||
{
|
x = x / Constants.RegionSize;
|
||||||
uint x, y;
|
y = y / Constants.RegionSize;
|
||||||
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("---> 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)));
|
//m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
|
||||||
if (Util.IsOutsideView(DrawDistance, x, newRegionX, 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
|
// Throttles
|
||||||
float multiplier = 1;
|
float multiplier = 1;
|
||||||
int childRegions = m_knownChildRegions.Count;
|
int childRegions = KnownRegionCount;
|
||||||
if (childRegions != 0)
|
if (childRegions != 0)
|
||||||
multiplier = 1f / childRegions;
|
multiplier = 1f / childRegions;
|
||||||
|
|
||||||
|
@ -3432,12 +3434,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
if (!IsChildAgent)
|
if (!IsChildAgent)
|
||||||
m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
|
m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
|
||||||
|
|
||||||
lock (m_knownChildRegions)
|
// Clear known regions
|
||||||
{
|
KnownRegions = new Dictionary<ulong, string>();
|
||||||
m_knownChildRegions.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (m_reprioritization_timer)
|
lock (m_reprioritization_timer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -215,11 +215,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||||
string cap = presence.ControllingClient.RequestClientInfo().CapsPath;
|
string cap = presence.ControllingClient.RequestClientInfo().CapsPath;
|
||||||
|
|
||||||
presence.AddNeighbourRegion(region2, cap);
|
presence.AddNeighbourRegion(region2, cap);
|
||||||
presence.AddNeighbourRegion(region3, cap);
|
presence.AddNeighbourRegion(region3, cap);
|
||||||
|
|
||||||
List<ulong> neighbours = presence.GetKnownRegionList();
|
Assert.That(presence.KnownRegionCount, Is.EqualTo(2));
|
||||||
|
|
||||||
Assert.That(neighbours.Count, Is.EqualTo(2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -230,8 +228,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||||
ScenePresence presence = scene.GetScenePresence(agent1);
|
ScenePresence presence = scene.GetScenePresence(agent1);
|
||||||
presence.RemoveNeighbourRegion(region3);
|
presence.RemoveNeighbourRegion(region3);
|
||||||
|
|
||||||
List<ulong> neighbours = presence.GetKnownRegionList();
|
Assert.That(presence.KnownRegionCount,Is.EqualTo(1));
|
||||||
Assert.That(neighbours.Count,Is.EqualTo(1));
|
|
||||||
/*
|
/*
|
||||||
presence.MakeChildAgent;
|
presence.MakeChildAgent;
|
||||||
presence.MakeRootAgent;
|
presence.MakeRootAgent;
|
||||||
|
|
Loading…
Reference in New Issue