diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f12d629cc0..8d72e18c80 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -311,7 +311,21 @@ namespace OpenSim.Region.Framework.Scenes /// private string m_callbackURI; - public UUID m_originRegionID; + /// + /// Records the region from which this presence originated, if not from login. + /// + /// + /// Also acts as a signal in the teleport V2 process to release UpdateAgent after a viewer has triggered + /// CompleteMovement and made the previous child agent a root agent. + /// + private UUID m_originRegionID; + + /// + /// This object is used as a lock before accessing m_originRegionID to make sure that every thread is seeing + /// the very latest value and not using some cached version. Cannot make m_originRegionID itself volatite as + /// it is a value type. + /// + private object m_originRegionIDAccessLock = new object(); /// /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent @@ -1359,13 +1373,21 @@ namespace OpenSim.Region.Framework.Scenes // m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero int count = 50; - while (m_originRegionID.Equals(UUID.Zero) && count-- > 0) + UUID originID; + + lock (m_originRegionIDAccessLock) + originID = m_originRegionID; + + while (originID.Equals(UUID.Zero) && count-- > 0) { + lock (m_originRegionIDAccessLock) + originID = m_originRegionID; + m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name); Thread.Sleep(200); } - if (m_originRegionID.Equals(UUID.Zero)) + if (originID.Equals(UUID.Zero)) { // Movement into region will fail m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name); @@ -1444,7 +1466,12 @@ namespace OpenSim.Region.Framework.Scenes "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", client.Name, client.AgentId, m_callbackURI); - Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); + UUID originID; + + lock (m_originRegionIDAccessLock) + originID = m_originRegionID; + + Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); m_callbackURI = null; } // else @@ -3461,7 +3488,8 @@ namespace OpenSim.Region.Framework.Scenes private void CopyFrom(AgentData cAgent) { - m_originRegionID = cAgent.RegionID; + lock (m_originRegionIDAccessLock) + m_originRegionID = cAgent.RegionID; m_callbackURI = cAgent.CallbackURI; // m_log.DebugFormat(