diff options
author | Diva Canto | 2013-07-22 11:54:35 -0700 |
---|---|---|
committer | Diva Canto | 2013-07-24 14:27:58 -0700 |
commit | 3891a8946bb72c9256d8de4185bf4a72c90be859 (patch) | |
tree | 3c4e2ca2468c287e1c0ea711ad6808bef0d82449 /OpenSim/Region/Framework | |
parent | Further tweaks on TPs: not sending the callback URL and instead waiting 15sec... (diff) | |
download | opensim-SC_OLD-3891a8946bb72c9256d8de4185bf4a72c90be859.zip opensim-SC_OLD-3891a8946bb72c9256d8de4185bf4a72c90be859.tar.gz opensim-SC_OLD-3891a8946bb72c9256d8de4185bf4a72c90be859.tar.bz2 opensim-SC_OLD-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.cs | 18 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 33 |
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; | |||
29 | using System.Xml; | 29 | using System.Xml; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Threading; | ||
32 | using System.Timers; | 33 | using System.Timers; |
34 | using Timer = System.Timers.Timer; | ||
33 | using OpenMetaverse; | 35 | using OpenMetaverse; |
34 | using log4net; | 36 | using log4net; |
35 | using Nini.Config; | 37 | using 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 | ||