diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 84 |
1 files changed, 62 insertions, 22 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index afe6daa..9481f71 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1245,11 +1245,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1245 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | 1245 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are |
1246 | // not transporting the required data. | 1246 | // not transporting the required data. |
1247 | // | 1247 | // |
1248 | // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT | ||
1249 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | ||
1250 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | ||
1251 | // not transporting the required data. | ||
1252 | // | ||
1253 | // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of | 1248 | // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of |
1254 | // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here | 1249 | // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here |
1255 | // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. | 1250 | // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. |
@@ -1258,22 +1253,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1258 | // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing | 1253 | // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing |
1259 | // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the | 1254 | // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the |
1260 | // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. | 1255 | // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. |
1261 | // | ||
1262 | // One cannot simply iterate over attachments in a fire and forget thread because this would no longer | ||
1263 | // be locked, allowing race conditions if other code changes the attachments list. | ||
1264 | List<SceneObjectGroup> attachments = GetAttachments(); | 1256 | List<SceneObjectGroup> attachments = GetAttachments(); |
1265 | 1257 | ||
1266 | if (attachments.Count > 0) | 1258 | if (attachments.Count > 0) |
1267 | { | 1259 | { |
1268 | m_log.DebugFormat( | 1260 | if (Watchdog.JobEngine.IsRunning) |
1269 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); | ||
1270 | |||
1271 | // Resume scripts | ||
1272 | foreach (SceneObjectGroup sog in attachments) | ||
1273 | { | 1261 | { |
1274 | sog.ScheduleGroupForFullUpdate(); | 1262 | Watchdog.RunWhenPossible( |
1275 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); | 1263 | "StartAttachmentScripts", |
1276 | sog.ResumeScripts(); | 1264 | o => RestartAttachmentScripts(attachments), |
1265 | string.Format("Start attachment scripts for {0} in {1}", Name, Scene.Name), | ||
1266 | null); | ||
1267 | } | ||
1268 | else | ||
1269 | { | ||
1270 | RestartAttachmentScripts(attachments); | ||
1277 | } | 1271 | } |
1278 | } | 1272 | } |
1279 | } | 1273 | } |
@@ -1298,6 +1292,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1298 | return true; | 1292 | return true; |
1299 | } | 1293 | } |
1300 | 1294 | ||
1295 | private void RestartAttachmentScripts(List<SceneObjectGroup> attachments) | ||
1296 | { | ||
1297 | m_log.DebugFormat( | ||
1298 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); | ||
1299 | |||
1300 | // Resume scripts | ||
1301 | foreach (SceneObjectGroup sog in attachments) | ||
1302 | { | ||
1303 | sog.ScheduleGroupForFullUpdate(); | ||
1304 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); | ||
1305 | sog.ResumeScripts(); | ||
1306 | } | ||
1307 | } | ||
1308 | |||
1301 | private static bool IsRealLogin(TeleportFlags teleportFlags) | 1309 | private static bool IsRealLogin(TeleportFlags teleportFlags) |
1302 | { | 1310 | { |
1303 | return ((teleportFlags & TeleportFlags.ViaLogin) != 0) && ((teleportFlags & TeleportFlags.ViaHGLogin) == 0); | 1311 | return ((teleportFlags & TeleportFlags.ViaLogin) != 0) && ((teleportFlags & TeleportFlags.ViaHGLogin) == 0); |
@@ -1813,13 +1821,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1813 | 1821 | ||
1814 | } | 1822 | } |
1815 | 1823 | ||
1816 | // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region | 1824 | // XXX: If we force an update after activity has completed, then multiple attachments do appear correctly on a destination region |
1817 | // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. | 1825 | // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. |
1818 | // This may be due to viewer code or it may be something we're not doing properly simulator side. | 1826 | // This may be due to viewer code or it may be something we're not doing properly simulator side. |
1819 | lock (m_attachments) | 1827 | if (Watchdog.JobEngine.IsRunning) |
1820 | { | 1828 | { |
1821 | foreach (SceneObjectGroup sog in m_attachments) | 1829 | Watchdog.RunWhenPossible( |
1822 | sog.ScheduleGroupForFullUpdate(); | 1830 | "ScheduleAttachmentsForFullUpdate", |
1831 | o => ScheduleAttachmentsForFullUpdate(), | ||
1832 | string.Format("Schedule attachments for full update for {0} in {1}", Name, Scene.Name), | ||
1833 | null); | ||
1834 | } | ||
1835 | else | ||
1836 | { | ||
1837 | ScheduleAttachmentsForFullUpdate(); | ||
1823 | } | 1838 | } |
1824 | 1839 | ||
1825 | // m_log.DebugFormat( | 1840 | // m_log.DebugFormat( |
@@ -1832,6 +1847,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1832 | } | 1847 | } |
1833 | } | 1848 | } |
1834 | 1849 | ||
1850 | private void ScheduleAttachmentsForFullUpdate() | ||
1851 | { | ||
1852 | lock (m_attachments) | ||
1853 | { | ||
1854 | foreach (SceneObjectGroup sog in m_attachments) | ||
1855 | sog.ScheduleGroupForFullUpdate(); | ||
1856 | } | ||
1857 | } | ||
1858 | |||
1835 | /// <summary> | 1859 | /// <summary> |
1836 | /// Callback for the Camera view block check. Gets called with the results of the camera view block test | 1860 | /// Callback for the Camera view block check. Gets called with the results of the camera view block test |
1837 | /// hitYN is true when there's something in the way. | 1861 | /// hitYN is true when there's something in the way. |
@@ -4039,9 +4063,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
4039 | Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero); | 4063 | Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero); |
4040 | 4064 | ||
4041 | if (Scene.AttachmentsModule != null) | 4065 | if (Scene.AttachmentsModule != null) |
4042 | Scene.AttachmentsModule.CopyAttachments(cAgent, this); | 4066 | { |
4067 | // If the JobEngine is running we can schedule this job now and continue rather than waiting for all | ||
4068 | // attachments to copy, which might take a long time in the Hypergrid case as the entire inventory | ||
4069 | // graph is inspected for each attachments and assets possibly fetched. | ||
4070 | // | ||
4071 | // We don't need to worry about a race condition as the job to later start the scripts is also | ||
4072 | // JobEngine scheduled and so will always occur after this task. | ||
4073 | // XXX: This will not be true if JobEngine ever gets more than one thread. | ||
4074 | if (Watchdog.JobEngine.IsRunning) | ||
4075 | Watchdog.RunWhenPossible( | ||
4076 | "CopyAttachments", | ||
4077 | o => Scene.AttachmentsModule.CopyAttachments(cAgent, this), | ||
4078 | string.Format("Copy attachments for {0} entering {1}", Name, Scene.Name), | ||
4079 | null); | ||
4080 | else | ||
4081 | Scene.AttachmentsModule.CopyAttachments(cAgent, this); | ||
4082 | } | ||
4043 | 4083 | ||
4044 | // This must occur after attachments are copied, as it releases the CompleteMovement() calling thread | 4084 | // This must occur after attachments are copied or scheduled to be copied, as it releases the CompleteMovement() calling thread |
4045 | // originating from the client completing a teleport. Otherwise, CompleteMovement() code to restart | 4085 | // originating from the client completing a teleport. Otherwise, CompleteMovement() code to restart |
4046 | // script attachments can outrace this thread. | 4086 | // script attachments can outrace this thread. |
4047 | lock (m_originRegionIDAccessLock) | 4087 | lock (m_originRegionIDAccessLock) |