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>
|
/// </summary>
|
||||||
private string m_callbackURI;
|
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>
|
/// <summary>
|
||||||
/// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
|
/// 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
|
// 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
|
// viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero
|
||||||
int count = 50;
|
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);
|
m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name);
|
||||||
Thread.Sleep(200);
|
Thread.Sleep(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_originRegionID.Equals(UUID.Zero))
|
if (originID.Equals(UUID.Zero))
|
||||||
{
|
{
|
||||||
// Movement into region will fail
|
// Movement into region will fail
|
||||||
m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name);
|
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}",
|
"[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
|
||||||
client.Name, client.AgentId, m_callbackURI);
|
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;
|
m_callbackURI = null;
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
|
@ -3461,6 +3488,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
private void CopyFrom(AgentData cAgent)
|
private void CopyFrom(AgentData cAgent)
|
||||||
{
|
{
|
||||||
|
lock (m_originRegionIDAccessLock)
|
||||||
m_originRegionID = cAgent.RegionID;
|
m_originRegionID = cAgent.RegionID;
|
||||||
|
|
||||||
m_callbackURI = cAgent.CallbackURI;
|
m_callbackURI = cAgent.CallbackURI;
|
||||||
|
|
Loading…
Reference in New Issue