aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-09-02 19:15:10 +0100
committerJustin Clark-Casey (justincc)2013-09-02 19:21:53 +0100
commit62b12783dfa6ed5f6b4921da302f356b4eac18f8 (patch)
tree1972b663cc8fbdc6372568a4ddf76ca702a2c0b9 /OpenSim/Region/Framework
parentComment out warning about agent updating without valid session ID for now. (diff)
downloadopensim-SC_OLD-62b12783dfa6ed5f6b4921da302f356b4eac18f8.zip
opensim-SC_OLD-62b12783dfa6ed5f6b4921da302f356b4eac18f8.tar.gz
opensim-SC_OLD-62b12783dfa6ed5f6b4921da302f356b4eac18f8.tar.bz2
opensim-SC_OLD-62b12783dfa6ed5f6b4921da302f356b4eac18f8.tar.xz
Fix bug where users teleporting to non-neighbour regions could continue to hear chat from their source region for some time after teleport completion.
This occurs on v2 teleport since the source region now waits 15 secs before closing the old child agent, which could still receive chat. This commit introduces a ScenePresenceState.PreClose which is set before the wait, so that ChatModule can check for ScenePresenceState.Running. This was theoretically also an issue on v1 teleport but since the pause before close was only 2 secs there, it was not noticed.
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs59
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs15
2 files changed, 67 insertions, 7 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 051c617..3eaa8fd 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -3695,10 +3695,13 @@ namespace OpenSim.Region.Framework.Scenes
3695 3695
3696 // We need to ensure that we are not already removing the scene presence before we ask it not to be 3696 // We need to ensure that we are not already removing the scene presence before we ask it not to be
3697 // closed. 3697 // closed.
3698 if (sp != null && sp.IsChildAgent && sp.LifecycleState == ScenePresenceState.Running) 3698 if (sp != null && sp.IsChildAgent
3699 && (sp.LifecycleState == ScenePresenceState.Running
3700 || sp.LifecycleState == ScenePresenceState.PreRemove))
3699 { 3701 {
3700 m_log.DebugFormat( 3702 m_log.DebugFormat(
3701 "[SCENE]: Reusing existing child scene presence for {0} in {1}", sp.Name, Name); 3703 "[SCENE]: Reusing existing child scene presence for {0}, state {1} in {2}",
3704 sp.Name, sp.LifecycleState, Name);
3702 3705
3703 // In the case where, for example, an A B C D region layout, an avatar may 3706 // In the case where, for example, an A B C D region layout, an avatar may
3704 // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C 3707 // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C
@@ -3720,6 +3723,8 @@ namespace OpenSim.Region.Framework.Scenes
3720// } 3723// }
3721// else if (EntityTransferModule.IsInTransit(sp.UUID)) 3724// else if (EntityTransferModule.IsInTransit(sp.UUID))
3722 3725
3726 sp.LifecycleState = ScenePresenceState.Running;
3727
3723 if (EntityTransferModule.IsInTransit(sp.UUID)) 3728 if (EntityTransferModule.IsInTransit(sp.UUID))
3724 { 3729 {
3725 sp.DoNotCloseAfterTeleport = true; 3730 sp.DoNotCloseAfterTeleport = true;
@@ -4454,6 +4459,50 @@ namespace OpenSim.Region.Framework.Scenes
4454 } 4459 }
4455 4460
4456 /// <summary> 4461 /// <summary>
4462 /// Tell a single agent to prepare to close.
4463 /// </summary>
4464 /// <remarks>
4465 /// This should only be called if we may close the agent but there will be some delay in so doing. Meant for
4466 /// internal use - other callers should almost certainly called IncomingCloseAgent().
4467 /// </remarks>
4468 /// <param name="sp"></param>
4469 /// <returns>true if pre-close state notification was successful. false if the agent
4470 /// was not in a state where it could transition to pre-close.</returns>
4471 public bool IncomingPreCloseAgent(ScenePresence sp)
4472 {
4473 lock (m_removeClientLock)
4474 {
4475 // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may
4476 // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not
4477 // want to obey this close since C may have renewed the child agent lease on B.
4478 if (sp.DoNotCloseAfterTeleport)
4479 {
4480 m_log.DebugFormat(
4481 "[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection",
4482 sp.IsChildAgent ? "child" : "root", sp.Name, Name);
4483
4484 // Need to reset the flag so that a subsequent close after another teleport can succeed.
4485 sp.DoNotCloseAfterTeleport = false;
4486
4487 return false;
4488 }
4489
4490 if (sp.LifecycleState != ScenePresenceState.Running)
4491 {
4492 m_log.DebugFormat(
4493 "[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}",
4494 sp.Name, Name, sp.LifecycleState);
4495
4496 return false;
4497 }
4498
4499 sp.LifecycleState = ScenePresenceState.PreRemove;
4500
4501 return true;
4502 }
4503 }
4504
4505 /// <summary>
4457 /// Tell a single agent to disconnect from the region. 4506 /// Tell a single agent to disconnect from the region.
4458 /// </summary> 4507 /// </summary>
4459 /// <param name="agentID"></param> 4508 /// <param name="agentID"></param>
@@ -4472,16 +4521,16 @@ namespace OpenSim.Region.Framework.Scenes
4472 if (sp == null) 4521 if (sp == null)
4473 { 4522 {
4474 m_log.DebugFormat( 4523 m_log.DebugFormat(
4475 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in {1}", 4524 "[SCENE]: Called IncomingCloseAgent() with agent ID {0} but no such presence is in {1}",
4476 agentID, Name); 4525 agentID, Name);
4477 4526
4478 return false; 4527 return false;
4479 } 4528 }
4480 4529
4481 if (sp.LifecycleState != ScenePresenceState.Running) 4530 if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove)
4482 { 4531 {
4483 m_log.DebugFormat( 4532 m_log.DebugFormat(
4484 "[SCENE]: Called RemoveClient() for {0} in {1} but presence is already in state {2}", 4533 "[SCENE]: Called IncomingCloseAgent() for {0} in {1} but presence is already in state {2}",
4485 sp.Name, Name, sp.LifecycleState); 4534 sp.Name, Name, sp.LifecycleState);
4486 4535
4487 return false; 4536 return false;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs b/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs
index dc3a212..cae7fe5 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs
@@ -37,7 +37,8 @@ namespace OpenSim.Region.Framework.Scenes
37 /// This is a state machine. 37 /// This is a state machine.
38 /// 38 ///
39 /// [Entry] => Running 39 /// [Entry] => Running
40 /// Running => Removing 40 /// Running => PreRemove, Removing
41 /// PreRemove => Running, Removing
41 /// Removing => Removed 42 /// Removing => Removed
42 /// 43 ///
43 /// All other methods should only see the scene presence in running state - this is the normal operational state 44 /// All other methods should only see the scene presence in running state - this is the normal operational state
@@ -46,6 +47,7 @@ namespace OpenSim.Region.Framework.Scenes
46 public enum ScenePresenceState 47 public enum ScenePresenceState
47 { 48 {
48 Running, // Normal operation state. The scene presence is available. 49 Running, // Normal operation state. The scene presence is available.
50 PreRemove, // The presence is due to be removed but can still be returning to running.
49 Removing, // The presence is in the process of being removed from the scene via Scene.RemoveClient. 51 Removing, // The presence is in the process of being removed from the scene via Scene.RemoveClient.
50 Removed, // The presence has been removed from the scene and is effectively dead. 52 Removed, // The presence has been removed from the scene and is effectively dead.
51 // There is no exit from this state. 53 // There is no exit from this state.
@@ -80,8 +82,17 @@ namespace OpenSim.Region.Framework.Scenes
80 82
81 lock (this) 83 lock (this)
82 { 84 {
83 if (newState == ScenePresenceState.Removing && m_state == ScenePresenceState.Running) 85 if (newState == m_state)
86 return;
87 else if (newState == ScenePresenceState.Running && m_state == ScenePresenceState.PreRemove)
84 transitionOkay = true; 88 transitionOkay = true;
89 else if (newState == ScenePresenceState.PreRemove && m_state == ScenePresenceState.Running)
90 transitionOkay = true;
91 else if (newState == ScenePresenceState.Removing)
92 {
93 if (m_state == ScenePresenceState.Running || m_state == ScenePresenceState.PreRemove)
94 transitionOkay = true;
95 }
85 else if (newState == ScenePresenceState.Removed && m_state == ScenePresenceState.Removing) 96 else if (newState == ScenePresenceState.Removed && m_state == ScenePresenceState.Removing)
86 transitionOkay = true; 97 transitionOkay = true;
87 } 98 }