aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs84
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)