diff options
author | Justin Clark-Casey (justincc) | 2014-10-14 16:57:58 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2014-11-25 23:21:38 +0000 |
commit | 1c9529aa9e7090cddbe120b0ecee50feaf672aa6 (patch) | |
tree | 4c04dccfa73bde7372db093e97d486daeef9fdf0 /OpenSim | |
parent | minor: be consistent about reporting errors out of HttpServerBase (diff) | |
download | opensim-SC_OLD-1c9529aa9e7090cddbe120b0ecee50feaf672aa6.zip opensim-SC_OLD-1c9529aa9e7090cddbe120b0ecee50feaf672aa6.tar.gz opensim-SC_OLD-1c9529aa9e7090cddbe120b0ecee50feaf672aa6.tar.bz2 opensim-SC_OLD-1c9529aa9e7090cddbe120b0ecee50feaf672aa6.tar.xz |
If JobEngine is active, then use it to copy/rez attachments for an avatar entering the scene that isn't initially logging on. This will execute tasks consecutively rather than concurrently.
This has two aims
1) Reduce initial teleport failures when a foreign Hypergrid user enters a region by not holding up the teleport for attachment rez (this can be particularly costly when HG gets all assets in the object graph.
2) Reduce server load that may impact other simulator activities.
This complements existing JobEngine options that perform initial login attachment rez and appearance send in consecutive tasks.
Diffstat (limited to 'OpenSim')
-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) |