diff options
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 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; |