diff options
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 24 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 31 |
2 files changed, 32 insertions, 23 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 87f0264..93a089d 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -1055,6 +1055,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1055 | 1055 | ||
1056 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); | 1056 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); |
1057 | 1057 | ||
1058 | // Need to signal neighbours whether child agents may need closing irrespective of whether this | ||
1059 | // one needed closing. We also need to close child agents as quickly as possible to avoid complicated | ||
1060 | // race conditions with rapid agent releporting (e.g. from A1 to a non-neighbour B, back | ||
1061 | // to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex | ||
1062 | // distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are | ||
1063 | // abandoned without proper close by viewer but then re-used by an incoming connection. | ||
1064 | sp.CloseChildAgents(newRegionX, newRegionY); | ||
1065 | |||
1058 | // May need to logout or other cleanup | 1066 | // May need to logout or other cleanup |
1059 | AgentHasMovedAway(sp, logout); | 1067 | AgentHasMovedAway(sp, logout); |
1060 | 1068 | ||
@@ -1064,17 +1072,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1064 | // Now let's make it officially a child agent | 1072 | // Now let's make it officially a child agent |
1065 | sp.MakeChildAgent(); | 1073 | sp.MakeChildAgent(); |
1066 | 1074 | ||
1067 | // May still need to signal neighbours whether child agents may need closing irrespective of whether this | ||
1068 | // one needed closing. Neighbour regions also contain logic to prevent a close if a subsequent move or | ||
1069 | // teleport re-established the child connection. | ||
1070 | // | ||
1071 | // It may be possible to also close child agents after a pause but one needs to be very careful about | ||
1072 | // race conditions between different regions on rapid teleporting (e.g. from A1 to a non-neighbour B, back | ||
1073 | // to a neighbour A2 then off to a non-neighbour C. Also, closing child agents early may be more compatible | ||
1074 | // with complicated scenarios where there a mixture of V1 and V2 teleports, though this is conjecture. It's | ||
1075 | // easier to close immediately and greatly reduce the scope of race conditions if possible. | ||
1076 | sp.CloseChildAgents(newRegionX, newRegionY); | ||
1077 | |||
1078 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 1075 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone |
1079 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 1076 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
1080 | { | 1077 | { |
@@ -1096,7 +1093,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1096 | } | 1093 | } |
1097 | else | 1094 | else |
1098 | { | 1095 | { |
1099 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {1}", sp.Name, Scene.Name); | 1096 | m_log.DebugFormat( |
1097 | "[ENTITY TRANSFER MODULE]: Connection for {0} in {1} has been re-established after teleport. Not closing.", | ||
1098 | sp.Name, Scene.Name); | ||
1099 | |||
1100 | sp.DoNotCloseAfterTeleport = false; | 1100 | sp.DoNotCloseAfterTeleport = false; |
1101 | } | 1101 | } |
1102 | } | 1102 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d187377..3e5ef10 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -3703,21 +3703,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
3703 | // In the case where, for example, an A B C D region layout, an avatar may | 3703 | // 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 | 3704 | // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C |
3705 | // renews the lease on the child agent at B, we must make sure that the close from A does not succeed. | 3705 | // renews the lease on the child agent at B, we must make sure that the close from A does not succeed. |
3706 | if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle)) | 3706 | // |
3707 | { | 3707 | // XXX: In the end, this should not be necessary if child agents are closed without delay on |
3708 | m_log.DebugFormat( | 3708 | // teleport, since realistically, the close request should always be processed before any other |
3709 | "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.", | 3709 | // region tried to re-establish a child agent. This is much simpler since the logic below is |
3710 | sp.Name, Name); | 3710 | // vulnerable to an issue when a viewer quits a region without sending a proper logout but then |
3711 | // re-establishes the connection on a relogin. This could wrongly set the DoNotCloseAfterTeleport | ||
3712 | // flag when no teleport had taken place (and hence no close was going to come). | ||
3713 | // if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle)) | ||
3714 | // { | ||
3715 | // m_log.DebugFormat( | ||
3716 | // "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.", | ||
3717 | // sp.Name, Name); | ||
3718 | // | ||
3719 | // sp.DoNotCloseAfterTeleport = true; | ||
3720 | // } | ||
3721 | // else if (EntityTransferModule.IsInTransit(sp.UUID)) | ||
3711 | 3722 | ||
3712 | sp.DoNotCloseAfterTeleport = true; | 3723 | if (EntityTransferModule.IsInTransit(sp.UUID)) |
3713 | } | ||
3714 | else if (EntityTransferModule.IsInTransit(sp.UUID)) | ||
3715 | { | 3724 | { |
3725 | sp.DoNotCloseAfterTeleport = true; | ||
3726 | |||
3716 | m_log.DebugFormat( | 3727 | m_log.DebugFormat( |
3717 | "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt previous end-of-teleport close.", | 3728 | "[SCENE]: Set DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt previous end-of-teleport close.", |
3718 | sp.Name, Name); | 3729 | sp.Name, Name); |
3719 | |||
3720 | sp.DoNotCloseAfterTeleport = true; | ||
3721 | } | 3730 | } |
3722 | } | 3731 | } |
3723 | } | 3732 | } |