diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index cb653ed15a..6286689f70 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -949,6 +949,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
neighbourRegion.RegionHandle);
return agent;
}
+ // No turning back
+ agent.IsChildAgent = true;
+
string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
@@ -1097,7 +1100,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
///
/// This informs all neighbouring regions about agent "avatar".
- /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
///
///
public void EnableChildAgents(ScenePresence sp)
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index a3dd53e1f5..65ffe92f62 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -140,7 +140,6 @@ namespace OpenSim.Region.Framework.Scenes
icon.EndInvoke(iar);
}
- ExpiringCache _failedSims = new ExpiringCache();
public void SendChildAgentDataUpdate(AgentPosition cAgentData, ScenePresence presence)
{
// This assumes that we know what our neighbors are.
@@ -158,15 +157,13 @@ namespace OpenSim.Region.Framework.Scenes
Utils.LongToUInts(regionHandle, out x, out y);
GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
bool v = true;
- if (! simulatorList.Contains(dest.ServerURI) && !_failedSims.TryGetValue(dest.ServerURI, out v))
+ if (! simulatorList.Contains(dest.ServerURI))
{
// we havent seen this simulator before, add it to the list
// and send it an update
simulatorList.Add(dest.ServerURI);
// Let move this to sync. Mono definitely does not like async networking.
- if (!m_scene.SimulationService.UpdateAgent(dest, cAgentData))
- // Also if it fails, get it out of the loop for a bit
- _failedSims.Add(dest.ServerURI, true, 120);
+ m_scene.SimulationService.UpdateAgent(dest, cAgentData);
// Leaving this here as a reminder that we tried, and it sucks.
//SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index b38523fa88..283de39390 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1255,7 +1255,7 @@ namespace OpenSim.Region.Framework.Scenes
{
IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface();
if (m_agentTransfer != null)
- m_agentTransfer.EnableChildAgents(this);
+ Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); });
IFriendsModule friendsModule = m_scene.RequestModuleInterface();
if (friendsModule != null)
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
index 8ab3b64065..4132ec7c3e 100644
--- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -153,6 +153,7 @@ namespace OpenSim.Services.Connectors.Simulation
return UpdateAgent(destination, (IAgentData)data, 200000); // yes, 200 seconds
}
+ private ExpiringCache _failedSims = new ExpiringCache();
///
/// Send updated position information about an agent in this region to a neighbor
/// This operation may be called very frequently if an avatar is moving about in
@@ -160,6 +161,10 @@ namespace OpenSim.Services.Connectors.Simulation
///
public bool UpdateAgent(GridRegion destination, AgentPosition data)
{
+ bool v = true;
+ if (_failedSims.TryGetValue(destination.ServerURI, out v))
+ return false;
+
// The basic idea of this code is that the first thread that needs to
// send an update for a specific avatar becomes the worker for any subsequent
// requests until there are no more outstanding requests. Further, only send the most
@@ -183,9 +188,10 @@ namespace OpenSim.Services.Connectors.Simulation
// Otherwise update the reference and start processing
m_updateAgentQueue[uri] = data;
}
-
+
AgentPosition pos = null;
- while (true)
+ bool success = true;
+ while (success)
{
lock (m_updateAgentQueue)
{
@@ -205,11 +211,16 @@ namespace OpenSim.Services.Connectors.Simulation
}
}
- UpdateAgent(destination, (IAgentData)pos, 10000);
+ success = UpdateAgent(destination, (IAgentData)pos, 10000);
}
-
- // unreachable
-// return true;
+ // we get here iff success == false
+ // blacklist sim for 2 minutes
+ lock (m_updateAgentQueue)
+ {
+ _failedSims.AddOrUpdate(destination.ServerURI, true, 120);
+ m_updateAgentQueue.Remove(uri);
+ }
+ return false;
}
///