diff options
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 16 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 61 |
2 files changed, 40 insertions, 37 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index ff7a062..4af4ddb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -341,11 +341,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
341 | if (!Enabled) | 341 | if (!Enabled) |
342 | return; | 342 | return; |
343 | 343 | ||
344 | if (DebugLevel > 0) | ||
345 | m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | ||
346 | |||
347 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | 344 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
348 | 345 | ||
346 | if (DebugLevel > 0) | ||
347 | m_log.DebugFormat( | ||
348 | "[ATTACHMENTS MODULE]: Saving for {0} attachments for {1} in {2}", | ||
349 | attachments.Count, sp.Name, m_scene.Name); | ||
350 | |||
349 | if (attachments.Count <= 0) | 351 | if (attachments.Count <= 0) |
350 | return; | 352 | return; |
351 | 353 | ||
@@ -359,6 +361,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
359 | // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from | 361 | // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from |
360 | // scripts performing attachment operations at the same time. Getting object states stops the scripts. | 362 | // scripts performing attachment operations at the same time. Getting object states stops the scripts. |
361 | scriptStates[so] = PrepareScriptInstanceForSave(so, false); | 363 | scriptStates[so] = PrepareScriptInstanceForSave(so, false); |
364 | |||
365 | // m_log.DebugFormat( | ||
366 | // "[ATTACHMENTS MODULE]: For object {0} for {1} in {2} got saved state {3}", | ||
367 | // so.Name, sp.Name, m_scene.Name, scriptStates[so]); | ||
362 | } | 368 | } |
363 | 369 | ||
364 | lock (sp.AttachmentsSyncLock) | 370 | lock (sp.AttachmentsSyncLock) |
@@ -826,8 +832,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
826 | { | 832 | { |
827 | if (DebugLevel > 0) | 833 | if (DebugLevel > 0) |
828 | m_log.DebugFormat( | 834 | m_log.DebugFormat( |
829 | "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", | 835 | "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} at pt {2} pos {3} {4} in {5}", |
830 | so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); | 836 | so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos, m_scene.Name); |
831 | 837 | ||
832 | // Remove from database and parcel prim count | 838 | // Remove from database and parcel prim count |
833 | m_scene.DeleteFromStorage(so.UUID); | 839 | m_scene.DeleteFromStorage(so.UUID); |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 93dfd00..0414f89 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1228,45 +1228,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
1228 | 1228 | ||
1229 | m_scene.SwapRootAgentCount(false); | 1229 | m_scene.SwapRootAgentCount(false); |
1230 | 1230 | ||
1231 | // The initial login scene presence is already root when it gets here | 1231 | if (Scene.AttachmentsModule != null) |
1232 | // and it has already rezzed the attachments and started their scripts. | 1232 | { |
1233 | // We do the following only for non-login agents, because their scripts | 1233 | // The initial login scene presence is already root when it gets here |
1234 | // haven't started yet. | 1234 | // and it has already rezzed the attachments and started their scripts. |
1235 | if (PresenceType == PresenceType.Npc || IsRealLogin(m_teleportFlags)) | 1235 | // We do the following only for non-login agents, because their scripts |
1236 | { | 1236 | // haven't started yet. |
1237 | // Viewers which have a current outfit folder will actually rez their own attachments. However, | 1237 | if (PresenceType == PresenceType.Npc || IsRealLogin(m_teleportFlags)) |
1238 | // viewers without (e.g. v1 viewers) will not, so we still need to make this call. | ||
1239 | if (Scene.AttachmentsModule != null) | ||
1240 | { | 1238 | { |
1239 | // Viewers which have a current outfit folder will actually rez their own attachments. However, | ||
1240 | // viewers without (e.g. v1 viewers) will not, so we still need to make this call. | ||
1241 | WorkManager.RunJob( | 1241 | WorkManager.RunJob( |
1242 | "RezAttachments", | 1242 | "RezAttachments", |
1243 | o => Scene.AttachmentsModule.RezAttachments(this), | 1243 | o => Scene.AttachmentsModule.RezAttachments(this), |
1244 | null, | 1244 | null, |
1245 | string.Format("Rez attachments for {0} in {1}", Name, Scene.Name)); | 1245 | string.Format("Rez attachments for {0} in {1}", Name, Scene.Name)); |
1246 | } | 1246 | } |
1247 | } | 1247 | else |
1248 | else | ||
1249 | { | ||
1250 | // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT | ||
1251 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | ||
1252 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | ||
1253 | // not transporting the required data. | ||
1254 | // | ||
1255 | // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of | ||
1256 | // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here | ||
1257 | // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. | ||
1258 | // | ||
1259 | // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts(). | ||
1260 | // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing | ||
1261 | // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the | ||
1262 | // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. | ||
1263 | List<SceneObjectGroup> attachments = GetAttachments(); | ||
1264 | |||
1265 | if (attachments.Count > 0) | ||
1266 | { | 1248 | { |
1267 | WorkManager.RunJob( | 1249 | WorkManager.RunJob( |
1268 | "StartAttachmentScripts", | 1250 | "StartAttachmentScripts", |
1269 | o => RestartAttachmentScripts(attachments), | 1251 | o => RestartAttachmentScripts(), |
1270 | null, | 1252 | null, |
1271 | string.Format("Start attachment scripts for {0} in {1}", Name, Scene.Name), | 1253 | string.Format("Start attachment scripts for {0} in {1}", Name, Scene.Name), |
1272 | true); | 1254 | true); |
@@ -1292,10 +1274,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
1292 | return true; | 1274 | return true; |
1293 | } | 1275 | } |
1294 | 1276 | ||
1295 | private void RestartAttachmentScripts(List<SceneObjectGroup> attachments) | 1277 | private void RestartAttachmentScripts() |
1296 | { | 1278 | { |
1279 | // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT | ||
1280 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | ||
1281 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | ||
1282 | // not transporting the required data. | ||
1283 | // | ||
1284 | // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of | ||
1285 | // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here | ||
1286 | // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. | ||
1287 | // | ||
1288 | // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts(). | ||
1289 | // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing | ||
1290 | // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the | ||
1291 | // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. | ||
1292 | List<SceneObjectGroup> attachments = GetAttachments(); | ||
1293 | |||
1297 | m_log.DebugFormat( | 1294 | m_log.DebugFormat( |
1298 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); | 1295 | "[SCENE PRESENCE]: Restarting scripts in {0} attachments for {1} in {2}", attachments.Count, Name, Scene.Name); |
1299 | 1296 | ||
1300 | // Resume scripts | 1297 | // Resume scripts |
1301 | foreach (SceneObjectGroup sog in attachments) | 1298 | foreach (SceneObjectGroup sog in attachments) |