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