diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7243db1..c2554d8 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -108,6 +108,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
111 | /// <summary> | ||
112 | /// This exists to prevent race conditions between two CompleteMovement threads if the simulator is slow and | ||
113 | /// the viewer fires these in quick succession. | ||
114 | /// </summary> | ||
115 | /// <remarks> | ||
116 | /// TODO: The child -> agent transition should be folded into LifecycleState and the CompleteMovement | ||
117 | /// regulation done there. | ||
118 | /// </remarks> | ||
119 | private object m_completeMovementLock = new object(); | ||
120 | |||
111 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); | 121 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); |
112 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); | 122 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); |
113 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); | 123 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); |
@@ -904,6 +914,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
904 | /// <summary> | 914 | /// <summary> |
905 | /// Turns a child agent into a root agent. | 915 | /// Turns a child agent into a root agent. |
906 | /// </summary> | 916 | /// </summary> |
917 | /// <remarks> | ||
907 | /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the | 918 | /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the |
908 | /// avatar is actual in the sim. They can perform all actions. | 919 | /// avatar is actual in the sim. They can perform all actions. |
909 | /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, | 920 | /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, |
@@ -911,8 +922,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
911 | /// | 922 | /// |
912 | /// This method is on the critical path for transferring an avatar from one region to another. Delay here | 923 | /// This method is on the critical path for transferring an avatar from one region to another. Delay here |
913 | /// delays that crossing. | 924 | /// delays that crossing. |
914 | /// </summary> | 925 | /// </remarks> |
915 | private void MakeRootAgent(Vector3 pos, bool isFlying) | 926 | private bool MakeRootAgent(Vector3 pos, bool isFlying) |
916 | { | 927 | { |
917 | // m_log.InfoFormat( | 928 | // m_log.InfoFormat( |
918 | // "[SCENE]: Upgrading child to root agent for {0} in {1}", | 929 | // "[SCENE]: Upgrading child to root agent for {0} in {1}", |
@@ -920,7 +931,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
920 | 931 | ||
921 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); | 932 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); |
922 | 933 | ||
923 | IsChildAgent = false; | 934 | lock (m_completeMovementLock) |
935 | { | ||
936 | if (!IsChildAgent) | ||
937 | return false; | ||
938 | |||
939 | IsChildAgent = false; | ||
940 | } | ||
924 | 941 | ||
925 | // Must reset this here so that a teleport to a region next to an existing region does not keep the flag | 942 | // Must reset this here so that a teleport to a region next to an existing region does not keep the flag |
926 | // set and prevent the close of the connection on a subsequent re-teleport. | 943 | // set and prevent the close of the connection on a subsequent re-teleport. |
@@ -1069,6 +1086,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1069 | 1086 | ||
1070 | m_scene.EventManager.TriggerOnMakeRootAgent(this); | 1087 | m_scene.EventManager.TriggerOnMakeRootAgent(this); |
1071 | 1088 | ||
1089 | return true; | ||
1072 | } | 1090 | } |
1073 | 1091 | ||
1074 | public int GetStateSource() | 1092 | public int GetStateSource() |
@@ -1442,7 +1460,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1442 | } | 1460 | } |
1443 | 1461 | ||
1444 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | 1462 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1445 | MakeRootAgent(AbsolutePosition, flying); | 1463 | if (!MakeRootAgent(AbsolutePosition, flying)) |
1464 | { | ||
1465 | m_log.DebugFormat( | ||
1466 | "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root", | ||
1467 | Name, Scene.Name); | ||
1468 | |||
1469 | return; | ||
1470 | } | ||
1446 | 1471 | ||
1447 | // Tell the client that we're totally ready | 1472 | // Tell the client that we're totally ready |
1448 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); | 1473 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); |