aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs59
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;