diff options
author | Justin Clark-Casey (justincc) | 2013-09-20 22:41:53 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2013-09-20 22:41:53 +0100 |
commit | c01db5fbdd982a9613d1d64e2ac54f1b5c73b63c (patch) | |
tree | e54784660ba2e6cb5e9d19d070593dcdb072953a | |
parent | Change some message log levels in Scene.IncomingUpdateChildAgent() for debugg... (diff) | |
download | opensim-SC-c01db5fbdd982a9613d1d64e2ac54f1b5c73b63c.zip opensim-SC-c01db5fbdd982a9613d1d64e2ac54f1b5c73b63c.tar.gz opensim-SC-c01db5fbdd982a9613d1d64e2ac54f1b5c73b63c.tar.bz2 opensim-SC-c01db5fbdd982a9613d1d64e2ac54f1b5c73b63c.tar.xz |
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.
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f12d629..8d72e18 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -311,7 +311,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
311 | /// </summary> | 311 | /// </summary> |
312 | private string m_callbackURI; | 312 | private string m_callbackURI; |
313 | 313 | ||
314 | public UUID m_originRegionID; | 314 | /// <summary> |
315 | /// Records the region from which this presence originated, if not from login. | ||
316 | /// </summary> | ||
317 | /// <remarks> | ||
318 | /// Also acts as a signal in the teleport V2 process to release UpdateAgent after a viewer has triggered | ||
319 | /// CompleteMovement and made the previous child agent a root agent. | ||
320 | /// </remarks> | ||
321 | private UUID m_originRegionID; | ||
322 | |||
323 | /// <summary> | ||
324 | /// This object is used as a lock before accessing m_originRegionID to make sure that every thread is seeing | ||
325 | /// the very latest value and not using some cached version. Cannot make m_originRegionID itself volatite as | ||
326 | /// it is a value type. | ||
327 | /// </summary> | ||
328 | private object m_originRegionIDAccessLock = new object(); | ||
315 | 329 | ||
316 | /// <summary> | 330 | /// <summary> |
317 | /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent | 331 | /// 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 | |||
1359 | // m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the | 1373 | // m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the |
1360 | // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero | 1374 | // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero |
1361 | int count = 50; | 1375 | int count = 50; |
1362 | while (m_originRegionID.Equals(UUID.Zero) && count-- > 0) | 1376 | UUID originID; |
1377 | |||
1378 | lock (m_originRegionIDAccessLock) | ||
1379 | originID = m_originRegionID; | ||
1380 | |||
1381 | while (originID.Equals(UUID.Zero) && count-- > 0) | ||
1363 | { | 1382 | { |
1383 | lock (m_originRegionIDAccessLock) | ||
1384 | originID = m_originRegionID; | ||
1385 | |||
1364 | m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name); | 1386 | m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name); |
1365 | Thread.Sleep(200); | 1387 | Thread.Sleep(200); |
1366 | } | 1388 | } |
1367 | 1389 | ||
1368 | if (m_originRegionID.Equals(UUID.Zero)) | 1390 | if (originID.Equals(UUID.Zero)) |
1369 | { | 1391 | { |
1370 | // Movement into region will fail | 1392 | // Movement into region will fail |
1371 | m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name); | 1393 | 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 | |||
1444 | "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", | 1466 | "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", |
1445 | client.Name, client.AgentId, m_callbackURI); | 1467 | client.Name, client.AgentId, m_callbackURI); |
1446 | 1468 | ||
1447 | Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); | 1469 | UUID originID; |
1470 | |||
1471 | lock (m_originRegionIDAccessLock) | ||
1472 | originID = m_originRegionID; | ||
1473 | |||
1474 | Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); | ||
1448 | m_callbackURI = null; | 1475 | m_callbackURI = null; |
1449 | } | 1476 | } |
1450 | // else | 1477 | // else |
@@ -3461,7 +3488,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3461 | 3488 | ||
3462 | private void CopyFrom(AgentData cAgent) | 3489 | private void CopyFrom(AgentData cAgent) |
3463 | { | 3490 | { |
3464 | m_originRegionID = cAgent.RegionID; | 3491 | lock (m_originRegionIDAccessLock) |
3492 | m_originRegionID = cAgent.RegionID; | ||
3465 | 3493 | ||
3466 | m_callbackURI = cAgent.CallbackURI; | 3494 | m_callbackURI = cAgent.CallbackURI; |
3467 | // m_log.DebugFormat( | 3495 | // m_log.DebugFormat( |