Lock around read/write of ScenePresence.m_originRegionID to make sure that all threads are seeing the latest value and not a cached one.
There is a possibilty that some V2 teleport failures are due to the viewer triggered CompleteMovement thread not seeing the change of m_originRegionID by the UpdateAgent thread.varregion
parent
c6dea6ee78
commit
c01db5fbdd
|
@ -311,7 +311,21 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </summary>
|
||||
private string m_callbackURI;
|
||||
|
||||
public UUID m_originRegionID;
|
||||
/// <summary>
|
||||
/// Records the region from which this presence originated, if not from login.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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.
|
||||
/// </remarks>
|
||||
private UUID m_originRegionID;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
private object m_originRegionIDAccessLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 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(
|
||||
|
|
Loading…
Reference in New Issue