aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs')
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs124
1 files changed, 97 insertions, 27 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index d0cab49..24d81d9 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -51,8 +51,9 @@ 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 || CleaningUp || [Exit] } 54 /// Preparing => { Transferring || Cancelling || CleaningUp || [Exit] }
55 /// Transferring => { ReceivedAtDestination || CleaningUp } 55 /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp }
56 /// Cancelling => CleaningUp
56 /// ReceivedAtDestination => CleaningUp 57 /// ReceivedAtDestination => CleaningUp
57 /// CleaningUp => [Exit] 58 /// CleaningUp => [Exit]
58 /// 59 ///
@@ -64,7 +65,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
64 Preparing, // The agent is being prepared for transfer 65 Preparing, // The agent is being prepared for transfer
65 Transferring, // The agent is in the process of being transferred to a destination 66 Transferring, // The agent is in the process of being transferred to a destination
66 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received 67 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received
67 CleaningUp // The agent is being changed to child/removed after a transfer 68 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.
68 } 70 }
69 71
70 /// <summary> 72 /// <summary>
@@ -115,42 +117,110 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
115 /// <param name='newState'></param> 117 /// <param name='newState'></param>
116 /// <returns></returns> 118 /// <returns></returns>
117 /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception> 119 /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
118 internal void UpdateInTransit(UUID id, AgentTransferState newState) 120 internal bool UpdateInTransit(UUID id, AgentTransferState newState)
119 { 121 {
122 bool transitionOkay = false;
123
124 // We don't want to throw an exception on cancel since this can come it at any time.
125 bool failIfNotOkay = true;
126
127 // Should be a failure message if failure is not okay.
128 string failureMessage = null;
129
130 AgentTransferState? oldState = null;
131
120 lock (m_agentsInTransit) 132 lock (m_agentsInTransit)
121 { 133 {
122 // Illegal to try and update an agent that's not actually in transit. 134 // Illegal to try and update an agent that's not actually in transit.
123 if (!m_agentsInTransit.ContainsKey(id)) 135 if (!m_agentsInTransit.ContainsKey(id))
124 throw new Exception( 136 {
125 string.Format( 137 if (newState != AgentTransferState.Cancelling)
126 "Agent with ID {0} is not registered as in transit in {1}", 138 failureMessage = string.Format(
127 id, m_mod.Scene.RegionInfo.RegionName)); 139 "Agent with ID {0} is not registered as in transit in {1}",
128 140 id, m_mod.Scene.RegionInfo.RegionName);
129 AgentTransferState oldState = m_agentsInTransit[id]; 141 else
142 failIfNotOkay = false;
143 }
144 else
145 {
146 oldState = m_agentsInTransit[id];
130 147
131 bool transitionOkay = false; 148 if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
149 {
150 transitionOkay = true;
151 }
152 else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing)
153 {
154 transitionOkay = true;
155 }
156 else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring)
157 {
158 transitionOkay = true;
159 }
160 else
161 {
162 if (newState == AgentTransferState.Cancelling
163 && (oldState == AgentTransferState.Preparing || oldState == AgentTransferState.Transferring))
164 {
165 transitionOkay = true;
166 }
167 else
168 {
169 failIfNotOkay = false;
170 }
171 }
132 172
133 if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) 173 if (!transitionOkay)
134 transitionOkay = true; 174 failureMessage
135 else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) 175 = string.Format(
136 transitionOkay = true; 176 "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}",
137 else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) 177 id, oldState, newState, m_mod.Scene.RegionInfo.RegionName);
138 transitionOkay = true; 178 }
139 179
140 if (transitionOkay) 180 if (transitionOkay)
181 {
141 m_agentsInTransit[id] = newState; 182 m_agentsInTransit[id] = newState;
142 else 183
143 throw new Exception( 184// m_log.DebugFormat(
144 string.Format( 185// "[ENTITY TRANSFER STATE MACHINE]: Changed agent with id {0} from state {1} to {2} in {3}",
145 "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}", 186// id, oldState, newState, m_mod.Scene.Name);
146 id, oldState, newState, m_mod.Scene.RegionInfo.RegionName)); 187 }
188 else if (failIfNotOkay)
189 {
190 throw new Exception(failureMessage);
191 }
192// else
193// {
194// if (oldState != null)
195// m_log.DebugFormat(
196// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} from state {1} to {2} in {3}",
197// id, oldState, newState, m_mod.Scene.Name);
198// else
199// m_log.DebugFormat(
200// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} to state {1} in {2} since agent not in transit",
201// id, newState, m_mod.Scene.Name);
202// }
147 } 203 }
204
205 return transitionOkay;
148 } 206 }
149 207
150 internal bool IsInTransit(UUID id) 208 /// <summary>
209 /// Gets the current agent transfer state.
210 /// </summary>
211 /// <returns>Null if the agent is not in transit</returns>
212 /// <param name='id'>
213 /// Identifier.
214 /// </param>
215 internal AgentTransferState? GetAgentTransferState(UUID id)
151 { 216 {
152 lock (m_agentsInTransit) 217 lock (m_agentsInTransit)
153 return m_agentsInTransit.ContainsKey(id); 218 {
219 if (!m_agentsInTransit.ContainsKey(id))
220 return null;
221 else
222 return m_agentsInTransit[id];
223 }
154 } 224 }
155 225
156 /// <summary> 226 /// <summary>
@@ -203,14 +273,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
203 273
204 lock (m_agentsInTransit) 274 lock (m_agentsInTransit)
205 { 275 {
206 if (!IsInTransit(id)) 276 AgentTransferState? currentState = GetAgentTransferState(id);
277
278 if (currentState == null)
207 throw new Exception( 279 throw new Exception(
208 string.Format( 280 string.Format(
209 "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit", 281 "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit",
210 id, m_mod.Scene.RegionInfo.RegionName)); 282 id, m_mod.Scene.RegionInfo.RegionName));
211 283
212 AgentTransferState currentState = m_agentsInTransit[id];
213
214 if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) 284 if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination)
215 throw new Exception( 285 throw new Exception(
216 string.Format( 286 string.Format(