aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs59
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs20
2 files changed, 69 insertions, 10 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 82358d8..5713e88 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -167,6 +167,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
167 167
168 if (!DisableInterRegionTeleportCancellation) 168 if (!DisableInterRegionTeleportCancellation)
169 client.OnTeleportCancel += OnClientCancelTeleport; 169 client.OnTeleportCancel += OnClientCancelTeleport;
170
171 client.OnConnectionClosed += OnConnectionClosed;
170 } 172 }
171 173
172 public virtual void Close() {} 174 public virtual void Close() {}
@@ -185,6 +187,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
185 187
186 #region Agent Teleports 188 #region Agent Teleports
187 189
190 private void OnConnectionClosed(IClientAPI client)
191 {
192 if (client.IsLoggingOut)
193 {
194 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting);
195
196 m_log.DebugFormat(
197 "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
198 client.Name, Scene.Name);
199 }
200 }
201
188 private void OnClientCancelTeleport(IClientAPI client) 202 private void OnClientCancelTeleport(IClientAPI client)
189 { 203 {
190 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling); 204 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling);
@@ -590,6 +604,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
590 return; 604 return;
591 } 605 }
592 606
607 Thread.Sleep(30000);
608
593 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) 609 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
594 { 610 {
595 m_log.DebugFormat( 611 m_log.DebugFormat(
@@ -598,6 +614,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
598 614
599 return; 615 return;
600 } 616 }
617 else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
618 {
619 m_log.DebugFormat(
620 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
621 sp.Name, finalDestination.RegionName, sp.Scene.Name);
622
623 return;
624 }
601 625
602 // Past this point we have to attempt clean up if the teleport fails, so update transfer state. 626 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
603 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 627 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
@@ -657,12 +681,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
657 681
658 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); 682 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
659 683
684 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
685 // establish th econnection to the destination which makes it return true.
686 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
687 {
688 m_log.DebugFormat(
689 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent",
690 sp.Name, finalDestination.RegionName, sp.Scene.Name);
691
692 return;
693 }
694
660 // A common teleport failure occurs when we can send CreateAgent to the 695 // A common teleport failure occurs when we can send CreateAgent to the
661 // destination region but the viewer cannot establish the connection (e.g. due to network issues between 696 // destination region but the viewer cannot establish the connection (e.g. due to network issues between
662 // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then 697 // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then
663 // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail(). 698 // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail().
664 if (!UpdateAgent(reg, finalDestination, agent, sp)) 699 if (!UpdateAgent(reg, finalDestination, agent, sp))
665 { 700 {
701 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
702 {
703 m_log.DebugFormat(
704 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
705 sp.Name, finalDestination.RegionName, sp.Scene.Name);
706
707 return;
708 }
709
666 m_log.WarnFormat( 710 m_log.WarnFormat(
667 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", 711 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
668 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 712 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
@@ -677,7 +721,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
677 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", 721 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
678 sp.Name, finalDestination.RegionName, sp.Scene.Name); 722 sp.Name, finalDestination.RegionName, sp.Scene.Name);
679 723
680 CleanupAbortedInterRegionTeleport(sp, finalDestination); 724 CleanupFailedInterRegionTeleport(sp, finalDestination);
681 725
682 return; 726 return;
683 } 727 }
@@ -706,6 +750,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
706 // that the client contacted the destination before we close things here. 750 // that the client contacted the destination before we close things here.
707 if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID)) 751 if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID))
708 { 752 {
753 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
754 {
755 m_log.DebugFormat(
756 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.",
757 sp.Name, finalDestination.RegionName, sp.Scene.Name);
758
759 return;
760 }
761
709 m_log.WarnFormat( 762 m_log.WarnFormat(
710 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", 763 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
711 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 764 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
@@ -772,7 +825,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
772 /// <remarks> 825 /// <remarks>
773 /// <param name='sp'> </param> 826 /// <param name='sp'> </param>
774 /// <param name='finalDestination'></param> 827 /// <param name='finalDestination'></param>
775 protected virtual void CleanupAbortedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) 828 protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination)
776 { 829 {
777 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 830 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
778 831
@@ -794,7 +847,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
794 /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param> 847 /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param>
795 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason) 848 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason)
796 { 849 {
797 CleanupAbortedInterRegionTeleport(sp, finalDestination); 850 CleanupFailedInterRegionTeleport(sp, finalDestination);
798 851
799 sp.ControllingClient.SendTeleportFailed( 852 sp.ControllingClient.SendTeleportFailed(
800 string.Format( 853 string.Format(
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index 7314727..fc02916 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -51,11 +51,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
51 /// This is a state machine. 51 /// This is a state machine.
52 /// 52 ///
53 /// [Entry] => Preparing 53 /// [Entry] => Preparing
54 /// Preparing => { Transferring || Cancelling || CleaningUp || [Exit] } 54 /// Preparing => { Transferring || Cancelling || CleaningUp || Aborting || [Exit] }
55 /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp } 55 /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp || Aborting }
56 /// Cancelling => CleaningUp 56 /// Cancelling => CleaningUp || Aborting
57 /// ReceivedAtDestination => CleaningUp 57 /// ReceivedAtDestination => CleaningUp || Aborting
58 /// CleaningUp => [Exit] 58 /// CleaningUp => [Exit]
59 /// Aborting => [Exit]
59 /// 60 ///
60 /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp 61 /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp
61 /// However, any state can transition to CleaningUp if the teleport has failed. 62 /// However, any state can transition to CleaningUp if the teleport has failed.
@@ -66,7 +67,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
66 Transferring, // The agent is in the process of being transferred to a destination 67 Transferring, // The agent is in the process of being transferred to a destination
67 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received 68 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received
68 CleaningUp, // The agent is being changed to child/removed after a transfer 69 CleaningUp, // The agent is being changed to child/removed after a transfer
69 Cancelling // The user has cancelled the teleport but we have yet to act upon this. 70 Cancelling, // The user has cancelled the teleport but we have yet to act upon this.
71 Aborting // The transfer is aborting. Unlike Cancelling, no compensating actions should be performed
70 } 72 }
71 73
72 /// <summary> 74 /// <summary>
@@ -134,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
134 // Illegal to try and update an agent that's not actually in transit. 136 // Illegal to try and update an agent that's not actually in transit.
135 if (!m_agentsInTransit.ContainsKey(id)) 137 if (!m_agentsInTransit.ContainsKey(id))
136 { 138 {
137 if (newState != AgentTransferState.Cancelling) 139 if (newState != AgentTransferState.Cancelling && newState != AgentTransferState.Aborting)
138 failureMessage = string.Format( 140 failureMessage = string.Format(
139 "Agent with ID {0} is not registered as in transit in {1}", 141 "Agent with ID {0} is not registered as in transit in {1}",
140 id, m_mod.Scene.RegionInfo.RegionName); 142 id, m_mod.Scene.RegionInfo.RegionName);
@@ -145,7 +147,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
145 { 147 {
146 oldState = m_agentsInTransit[id]; 148 oldState = m_agentsInTransit[id];
147 149
148 if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) 150 if (newState == AgentTransferState.Aborting)
151 {
152 transitionOkay = true;
153 }
154 else if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
149 { 155 {
150 transitionOkay = true; 156 transitionOkay = true;
151 } 157 }