aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-08-15 13:46:46 +0100
committerJustin Clark-Casey (justincc)2013-08-15 13:46:46 +0100
commit2231fcf5b45be9a2f5b6e1a2665ff7223e275b33 (patch)
tree7d473725fe4240a272eb30099f17fa9bc285eb3c
parentActually implement the bot request object textures switch started in 225cf0d. (diff)
downloadopensim-SC_OLD-2231fcf5b45be9a2f5b6e1a2665ff7223e275b33.zip
opensim-SC_OLD-2231fcf5b45be9a2f5b6e1a2665ff7223e275b33.tar.gz
opensim-SC_OLD-2231fcf5b45be9a2f5b6e1a2665ff7223e275b33.tar.bz2
opensim-SC_OLD-2231fcf5b45be9a2f5b6e1a2665ff7223e275b33.tar.xz
Do not use the SP.DoNotCloseAfterTeleport flag for child agent connections.
This approach has problems if a client quits without sending a proper logout but then reconnects before the connection is closed due to inactivity. In this case, the DoNotCloseAfterTeleport was wrongly set. The simplest approach is to close child agents on teleport as quickly as possible so that races are very unlikely to occur Hence, this code now closes child agents as the first action after a sucessful teleport.
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs31
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 }