diff options
author | Justin Clark-Casey (justincc) | 2013-09-02 19:15:10 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2013-09-02 19:15:10 +0100 |
commit | 857f24a5e2b59072ad4d987d5e64318f5249c7e7 (patch) | |
tree | fb2bdcae26a3eb6290ed9a587cf729172bf4f8a2 /OpenSim/Region/Framework/Scenes/Scene.cs | |
parent | Comment out warning about agent updating without valid session ID for now. (diff) | |
download | opensim-SC_OLD-857f24a5e2b59072ad4d987d5e64318f5249c7e7.zip opensim-SC_OLD-857f24a5e2b59072ad4d987d5e64318f5249c7e7.tar.gz opensim-SC_OLD-857f24a5e2b59072ad4d987d5e64318f5249c7e7.tar.bz2 opensim-SC_OLD-857f24a5e2b59072ad4d987d5e64318f5249c7e7.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/Scenes/Scene.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 005c9b9..2a21a4c 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; |
@@ -4441,6 +4446,50 @@ namespace OpenSim.Region.Framework.Scenes | |||
4441 | } | 4446 | } |
4442 | 4447 | ||
4443 | /// <summary> | 4448 | /// <summary> |
4449 | /// Tell a single agent to prepare to close. | ||
4450 | /// </summary> | ||
4451 | /// <remarks> | ||
4452 | /// This should only be called if we may close the agent but there will be some delay in so doing. Meant for | ||
4453 | /// internal use - other callers should almost certainly called IncomingCloseAgent(). | ||
4454 | /// </remarks> | ||
4455 | /// <param name="sp"></param> | ||
4456 | /// <returns>true if pre-close state notification was successful. false if the agent | ||
4457 | /// was not in a state where it could transition to pre-close.</returns> | ||
4458 | public bool IncomingPreCloseAgent(ScenePresence sp) | ||
4459 | { | ||
4460 | lock (m_removeClientLock) | ||
4461 | { | ||
4462 | // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may | ||
4463 | // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not | ||
4464 | // want to obey this close since C may have renewed the child agent lease on B. | ||
4465 | if (sp.DoNotCloseAfterTeleport) | ||
4466 | { | ||
4467 | m_log.DebugFormat( | ||
4468 | "[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection", | ||
4469 | sp.IsChildAgent ? "child" : "root", sp.Name, Name); | ||
4470 | |||
4471 | // Need to reset the flag so that a subsequent close after another teleport can succeed. | ||
4472 | sp.DoNotCloseAfterTeleport = false; | ||
4473 | |||
4474 | return false; | ||
4475 | } | ||
4476 | |||
4477 | if (sp.LifecycleState != ScenePresenceState.Running) | ||
4478 | { | ||
4479 | m_log.DebugFormat( | ||
4480 | "[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}", | ||
4481 | sp.Name, Name, sp.LifecycleState); | ||
4482 | |||
4483 | return false; | ||
4484 | } | ||
4485 | |||
4486 | sp.LifecycleState = ScenePresenceState.PreRemove; | ||
4487 | |||
4488 | return true; | ||
4489 | } | ||
4490 | } | ||
4491 | |||
4492 | /// <summary> | ||
4444 | /// Tell a single agent to disconnect from the region. | 4493 | /// Tell a single agent to disconnect from the region. |
4445 | /// </summary> | 4494 | /// </summary> |
4446 | /// <param name="agentID"></param> | 4495 | /// <param name="agentID"></param> |
@@ -4459,16 +4508,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
4459 | if (sp == null) | 4508 | if (sp == null) |
4460 | { | 4509 | { |
4461 | m_log.DebugFormat( | 4510 | m_log.DebugFormat( |
4462 | "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in {1}", | 4511 | "[SCENE]: Called IncomingCloseAgent() with agent ID {0} but no such presence is in {1}", |
4463 | agentID, Name); | 4512 | agentID, Name); |
4464 | 4513 | ||
4465 | return false; | 4514 | return false; |
4466 | } | 4515 | } |
4467 | 4516 | ||
4468 | if (sp.LifecycleState != ScenePresenceState.Running) | 4517 | if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove) |
4469 | { | 4518 | { |
4470 | m_log.DebugFormat( | 4519 | m_log.DebugFormat( |
4471 | "[SCENE]: Called RemoveClient() for {0} in {1} but presence is already in state {2}", | 4520 | "[SCENE]: Called IncomingCloseAgent() for {0} in {1} but presence is already in state {2}", |
4472 | sp.Name, Name, sp.LifecycleState); | 4521 | sp.Name, Name, sp.LifecycleState); |
4473 | 4522 | ||
4474 | return false; | 4523 | return false; |