From e5b739aaebace6b028f3f6bf05d21ff7a7c5affe Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 25 Jun 2012 22:48:13 +0100
Subject: When attachments are being saved and deleted for a closing root
agent, delete first to avoid a hud race condition with update threads.
If delete doesn't occur first then the update thread can outrace the IsAttachment = false necessary to save attachments and send hud artifacts to other viewers.
---
.../Avatar/Attachments/AttachmentsModule.cs | 33 ++++++++++++++--------
.../Framework/Interfaces/IAttachmentsModule.cs | 11 ++++++--
OpenSim/Region/Framework/Scenes/Scene.cs | 24 ++++++++--------
OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 --
4 files changed, 42 insertions(+), 29 deletions(-)
(limited to 'OpenSim/Region')
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 99e0153..2b0e4ab 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -152,31 +152,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
}
}
- public void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted)
+ public void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted)
{
-// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
-
if (!Enabled)
return;
- foreach (SceneObjectGroup grp in sp.GetAttachments())
+// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
+
+ lock (sp.AttachmentsSyncLock)
{
- grp.IsAttachment = false;
- grp.AbsolutePosition = grp.RootPart.AttachedPos;
- UpdateKnownItem(sp, grp, saveAllScripted);
- grp.IsAttachment = true;
+ foreach (SceneObjectGroup grp in sp.GetAttachments())
+ {
+ grp.Scene.DeleteSceneObject(grp, false);
+
+ if (saveChanged || saveAllScripted)
+ {
+ grp.IsAttachment = false;
+ grp.AbsolutePosition = grp.RootPart.AttachedPos;
+ UpdateKnownItem(sp, grp, saveAllScripted);
+ }
+ }
+
+ sp.ClearAttachments();
}
}
public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent)
{
-// m_log.DebugFormat(
-// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
-// m_scene.RegionInfo.RegionName, sp.Name, silent);
-
if (!Enabled)
return;
+// m_log.DebugFormat(
+// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
+// m_scene.RegionInfo.RegionName, sp.Name, silent);
+
foreach (SceneObjectGroup sop in sp.GetAttachments())
{
sop.Scene.DeleteSceneObject(sop, silent);
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index eb07165..fde5de1 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -43,10 +43,15 @@ namespace OpenSim.Region.Framework.Interfaces
void RezAttachments(IScenePresence sp);
///
- /// Save the attachments that have change on this presence.
+ /// Derez the attachements for a scene presence that is closing.
///
- ///
- void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted);
+ ///
+ /// Attachment changes are saved.
+ ///
+ /// The presence closing
+ /// Save changed attachments.
+ /// Save attachments with scripts even if they haven't changed.
+ void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted);
///
/// Delete all the presence's attachments from the scene
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 385febf..d449116 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -500,6 +500,7 @@ namespace OpenSim.Region.Framework.Scenes
public IAttachmentsModule AttachmentsModule { get; set; }
public IEntityTransferModule EntityTransferModule { get; private set; }
public IAgentAssetTransactions AgentTransactionsModule { get; private set; }
+ public IUserManagement UserManagementModule { get; private set; }
public IAvatarFactoryModule AvatarFactory
{
@@ -1243,6 +1244,7 @@ namespace OpenSim.Region.Framework.Scenes
EntityTransferModule = RequestModuleInterface();
m_groupsModule = RequestModuleInterface();
AgentTransactionsModule = RequestModuleInterface();
+ UserManagementModule = RequestModuleInterface();
}
#endregion
@@ -2021,9 +2023,8 @@ namespace OpenSim.Region.Framework.Scenes
sceneObject.SetGroup(groupID, null);
}
- IUserManagement uman = RequestModuleInterface();
- if (uman != null)
- sceneObject.RootPart.CreatorIdentification = uman.GetUserUUI(ownerID);
+ if (UserManagementModule != null)
+ sceneObject.RootPart.CreatorIdentification = UserManagementModule.GetUserUUI(ownerID);
sceneObject.ScheduleGroupForFullUpdate();
@@ -2711,14 +2712,13 @@ namespace OpenSim.Region.Framework.Scenes
///
private void CacheUserName(ScenePresence sp, AgentCircuitData aCircuit)
{
- IUserManagement uMan = RequestModuleInterface();
- if (uMan != null)
+ if (UserManagementModule != null)
{
string first = aCircuit.firstname, last = aCircuit.lastname;
if (sp.PresenceType == PresenceType.Npc)
{
- uMan.AddUser(aCircuit.AgentID, first, last);
+ UserManagementModule.AddUser(aCircuit.AgentID, first, last);
}
else
{
@@ -2737,7 +2737,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- uMan.AddUser(aCircuit.AgentID, first, last, homeURL);
+ UserManagementModule.AddUser(aCircuit.AgentID, first, last, homeURL);
}
}
}
@@ -3292,17 +3292,19 @@ namespace OpenSim.Region.Framework.Scenes
if (!isChildAgent)
{
- if (AttachmentsModule != null && avatar.PresenceType != PresenceType.Npc)
+ if (AttachmentsModule != null)
{
- IUserManagement uMan = RequestModuleInterface();
// Don't save attachments for HG visitors, it
// messes up their inventory. When a HG visitor logs
// out on a foreign grid, their attachments will be
// reloaded in the state they were in when they left
// the home grid. This is best anyway as the visited
// grid may use an incompatible script engine.
- if (uMan == null || uMan.IsLocalGridUser(avatar.UUID))
- AttachmentsModule.SaveChangedAttachments(avatar, false);
+ bool saveChanged
+ = avatar.PresenceType != PresenceType.Npc
+ && (UserManagementModule == null || UserManagementModule.IsLocalGridUser(avatar.UUID));
+
+ AttachmentsModule.DeRezAttachments(avatar, saveChanged, false);
}
ForEachClient(
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 3909fd4..909c7c8 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -3416,9 +3416,6 @@ namespace OpenSim.Region.Framework.Scenes
public void Close()
{
- if (!IsChildAgent && m_scene.AttachmentsModule != null)
- m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
-
// Clear known regions
KnownRegions = new Dictionary();
--
cgit v1.1