aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
authorDiva Canto2013-07-22 11:54:35 -0700
committerDiva Canto2013-07-24 14:27:58 -0700
commit3891a8946bb72c9256d8de4185bf4a72c90be859 (patch)
tree3c4e2ca2468c287e1c0ea711ad6808bef0d82449 /OpenSim/Region/Framework
parentFurther tweaks on TPs: not sending the callback URL and instead waiting 15sec... (diff)
downloadopensim-SC-3891a8946bb72c9256d8de4185bf4a72c90be859.zip
opensim-SC-3891a8946bb72c9256d8de4185bf4a72c90be859.tar.gz
opensim-SC-3891a8946bb72c9256d8de4185bf4a72c90be859.tar.bz2
opensim-SC-3891a8946bb72c9256d8de4185bf4a72c90be859.tar.xz
New Teleport protocol (V2), still compatible with V1 and older. (version of the destination is being checked)
In this new protocol, and as committed before, the viewer is not sent EnableSimulator/EstablishChildCommunication for the destination. Instead, it is sent TeleportFinish directly. TeleportFinish, in turn, makes the viewer send a UserCircuitCode packet followed by CompleteMovementIntoRegion packet. These 2 packets tend to occur one after the other almost immediately to the point that when CMIR arrives the client is not even connected yet and that packet is ignored (there might have been some race conditions here before); then the viewer sends CMIR again within 5-8 secs. But the delay between them may be higher in busier regions, which may lead to race conditions. This commit improves the process so there are are no race conditions at the destination. CompleteMovement (triggered by the viewer) waits until Update has been sent from the origin. Update, in turn, waits until there is a *root* scene presence -- so making sure CompleteMovement has run MakeRoot. In other words, there are two threadlets at the destination, one from the viewer and one from the origin region, waiting for each other to do the right thing. That makes it safe to close the agent at the origin upon return of the Update call without having to wait for callback, because we are absolutely sure that the viewer knows it is in th new region. Note also that in the V1 protocol, the destination was getting UseCircuitCode from the viewer twice -- once on EstablishAgentCommunication and then again on TeleportFinish. The second UCC was being ignored, but it shows how we were not following the expected steps...
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs18
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs33
2 files changed, 45 insertions, 6 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index d4ef3d9..da8a1b8 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4221,6 +4221,20 @@ namespace OpenSim.Region.Framework.Scenes
4221 } 4221 }
4222 4222
4223 childAgentUpdate.ChildAgentDataUpdate(cAgentData); 4223 childAgentUpdate.ChildAgentDataUpdate(cAgentData);
4224
4225 int ntimes = 20;
4226 if (cAgentData.SenderWantsToWaitForRoot)
4227 {
4228 while (childAgentUpdate.IsChildAgent && ntimes-- > 0)
4229 Thread.Sleep(500);
4230
4231 m_log.DebugFormat(
4232 "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits",
4233 childAgentUpdate.Name, childAgentUpdate.UUID, childAgentUpdate.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 20 - ntimes);
4234
4235 if (childAgentUpdate.IsChildAgent)
4236 return false;
4237 }
4224 return true; 4238 return true;
4225 } 4239 }
4226 return false; 4240 return false;
@@ -4278,10 +4292,6 @@ namespace OpenSim.Region.Framework.Scenes
4278 m_log.WarnFormat( 4292 m_log.WarnFormat(
4279 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", 4293 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout",
4280 agentID, RegionInfo.RegionName); 4294 agentID, RegionInfo.RegionName);
4281// else
4282// m_log.DebugFormat(
4283// "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits",
4284// sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 10 - ntimes);
4285 4295
4286 return sp; 4296 return sp;
4287 } 4297 }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 6433878..891e04e 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -29,7 +29,9 @@ using System;
29using System.Xml; 29using System.Xml;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection; 31using System.Reflection;
32using System.Threading;
32using System.Timers; 33using System.Timers;
34using Timer = System.Timers.Timer;
33using OpenMetaverse; 35using OpenMetaverse;
34using log4net; 36using log4net;
35using Nini.Config; 37using Nini.Config;
@@ -1311,6 +1313,26 @@ namespace OpenSim.Region.Framework.Scenes
1311 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1313 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1312 } 1314 }
1313 1315
1316 private bool WaitForUpdateAgent(IClientAPI client)
1317 {
1318 // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero
1319 int count = 20;
1320 while (m_originRegionID.Equals(UUID.Zero) && count-- > 0)
1321 {
1322 m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.RegionInfo.RegionName);
1323 Thread.Sleep(200);
1324 }
1325
1326 if (m_originRegionID.Equals(UUID.Zero))
1327 {
1328 // Movement into region will fail
1329 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived", client.Name);
1330 return false;
1331 }
1332
1333 return true;
1334 }
1335
1314 /// <summary> 1336 /// <summary>
1315 /// Complete Avatar's movement into the region. 1337 /// Complete Avatar's movement into the region.
1316 /// </summary> 1338 /// </summary>
@@ -1328,6 +1350,12 @@ namespace OpenSim.Region.Framework.Scenes
1328 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", 1350 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
1329 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); 1351 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition);
1330 1352
1353 if (m_teleportFlags != TeleportFlags.ViaLogin)
1354 // Let's wait until UpdateAgent (called by departing region) is done
1355 if (!WaitForUpdateAgent(client))
1356 // The sending region never sent the UpdateAgent data, we have to refuse
1357 return;
1358
1331 Vector3 look = Velocity; 1359 Vector3 look = Velocity;
1332 1360
1333 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1361 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
@@ -1348,10 +1376,11 @@ namespace OpenSim.Region.Framework.Scenes
1348 1376
1349 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1377 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1350 MakeRootAgent(AbsolutePosition, flying); 1378 MakeRootAgent(AbsolutePosition, flying);
1379
1380 // Tell the client that we're totally ready
1351 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); 1381 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1382
1352 // Remember in HandleUseCircuitCode, we delayed this to here 1383 // Remember in HandleUseCircuitCode, we delayed this to here
1353 // This will also send the initial data to clients when TP to a neighboring region.
1354 // Not ideal, but until we know we're TP-ing from a neighboring region, there's not much we can do
1355 if (m_teleportFlags > 0) 1384 if (m_teleportFlags > 0)
1356 SendInitialDataToMe(); 1385 SendInitialDataToMe();
1357 1386