aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-03-12 22:16:09 +0000
committerJustin Clark-Casey (justincc)2013-03-12 22:16:09 +0000
commitc43d4b557267547d07f6c90dc7e335ce4f7e07be (patch)
treebaa7c11fae0e9c7e51cb173ba4c8182a8a5515c3 /OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
parentminor: remove mono compiler warning in SceneObjectUndoRedoTests (diff)
downloadopensim-SC_OLD-c43d4b557267547d07f6c90dc7e335ce4f7e07be.zip
opensim-SC_OLD-c43d4b557267547d07f6c90dc7e335ce4f7e07be.tar.gz
opensim-SC_OLD-c43d4b557267547d07f6c90dc7e335ce4f7e07be.tar.bz2
opensim-SC_OLD-c43d4b557267547d07f6c90dc7e335ce4f7e07be.tar.xz
Improve teleport cancellation in some circumstances, though cancelling teleports is still not recommended.
Previously, hitting the cancel button on a teleport would cancel on the client side but the request was ignored on the server side. Cancel would still work if the teleport failed in the early stages (e.g. because the destination never replied to early CreateAgent and UpdateAgent messages). But if the teleport still completed after a delay here or later on, the viewer would become confused (usual symptom appears to be avatar being unable to move/reteleport). This commit makes OpenSimulator obey cancellations which are received before it sends the TeleportFinish event queue message and does proper cleanup. But cancellations received after this (which can happen even though the cancel button is removed as this messages comes on a different thread) can still result in a frozen avatar. This looks extremely difficult and impossible to fix. I can replicate the same problem on the Linden Lab grid by hitting cancel immediately after a teleport starts (a teleport which would otherwise quickly succeed).
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs59
1 files changed, 52 insertions, 7 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 01b1668..34f0924 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -148,6 +148,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
148 148
149 protected virtual void OnNewClient(IClientAPI client) 149 protected virtual void OnNewClient(IClientAPI client)
150 { 150 {
151 client.OnTeleportCancel += OnClientCancelTeleport;
151 client.OnTeleportHomeRequest += TeleportHome; 152 client.OnTeleportHomeRequest += TeleportHome;
152 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 153 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
153 } 154 }
@@ -168,6 +169,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
168 169
169 #region Agent Teleports 170 #region Agent Teleports
170 171
172 private void OnClientCancelTeleport(IClientAPI client)
173 {
174 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling);
175
176 m_log.DebugFormat(
177 "[ENTITY TRANSFER MODULE]: Received teleport cancel request from {0} in {1}", client.Name, Scene.Name);
178 }
179
171 public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) 180 public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags)
172 { 181 {
173 if (sp.Scene.Permissions.IsGridGod(sp.UUID)) 182 if (sp.Scene.Permissions.IsGridGod(sp.UUID))
@@ -567,6 +576,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
567 return; 576 return;
568 } 577 }
569 578
579 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
580 {
581 m_log.DebugFormat(
582 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
583 sp.Name, finalDestination.RegionName, sp.Scene.Name);
584
585 return;
586 }
587
570 // Past this point we have to attempt clean up if the teleport fails, so update transfer state. 588 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
571 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 589 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
572 590
@@ -631,7 +649,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
631 return; 649 return;
632 } 650 }
633 651
634 sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); 652 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
653 {
654 m_log.DebugFormat(
655 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
656 sp.Name, finalDestination.RegionName, sp.Scene.Name);
657
658 CleanupAbortedInterRegionTeleport(sp, finalDestination);
659
660 return;
661 }
635 662
636 m_log.DebugFormat( 663 m_log.DebugFormat(
637 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", 664 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
@@ -714,14 +741,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
714// } 741// }
715 } 742 }
716 743
717 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) 744 /// <summary>
745 /// Clean up an inter-region teleport that did not complete, either because of simulator failure or cancellation.
746 /// </summary>
747 /// <remarks>
748 /// All operations here must be idempotent so that we can call this method at any point in the teleport process
749 /// up until we send the TeleportFinish event quene event to the viewer.
750 /// <remarks>
751 /// <param name='sp'> </param>
752 /// <param name='finalDestination'></param>
753 protected virtual void CleanupAbortedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination)
718 { 754 {
719 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 755 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
720 756
721 // Client never contacted destination. Let's restore everything back
722 sp.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
723
724 // Fail. Reset it back
725 sp.IsChildAgent = false; 757 sp.IsChildAgent = false;
726 ReInstantiateScripts(sp); 758 ReInstantiateScripts(sp);
727 759
@@ -729,7 +761,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
729 761
730 // Finally, kill the agent we just created at the destination. 762 // Finally, kill the agent we just created at the destination.
731 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); 763 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID);
764 }
765
766 /// <summary>
767 /// Signal that the inter-region teleport failed and perform cleanup.
768 /// </summary>
769 /// <param name='sp'></param>
770 /// <param name='finalDestination'></param>
771 /// <param name='logout'></param>
772 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
773 {
774 CleanupAbortedInterRegionTeleport(sp, finalDestination);
732 775
776 sp.ControllingClient.SendTeleportFailed(
777 string.Format("Problems connecting to destination {0}", finalDestination.RegionName));
733 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); 778 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
734 } 779 }
735 780
@@ -2097,7 +2142,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2097 2142
2098 public bool IsInTransit(UUID id) 2143 public bool IsInTransit(UUID id)
2099 { 2144 {
2100 return m_entityTransferStateMachine.IsInTransit(id); 2145 return m_entityTransferStateMachine.GetAgentTransferState(id) != null;
2101 } 2146 }
2102 2147
2103 protected void ReInstantiateScripts(ScenePresence sp) 2148 protected void ReInstantiateScripts(ScenePresence sp)