From 32444d98cb13423fdf8c874e4fbb7ea17670d7c5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 31 Aug 2011 16:29:51 +0100 Subject: Make SP.Attachments available as sp.GetAttachments() instead. The approach here, as in other parts of OpenSim, is to return a copy of the list rather than the attachments list itself This prevents callers from forgetting to lock the list when they read it, as was happening in various parts of the codebase. It also improves liveness. This might improve attachment anomolies when performing region crossings. --- .../Region/Framework/Interfaces/IScenePresence.cs | 7 ++- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 51 ++++++++++++++++------ 2 files changed, 43 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs index b07c821..788b36f 100644 --- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs +++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs @@ -58,10 +58,13 @@ namespace OpenSim.Region.Framework.Interfaces /// /// The scene objects attached to this avatar. /// + /// + /// A copy of the list. + /// /// /// Do not change this list directly - use methods such as - /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. + /// AddAttachment() and RemoveAttachment(). /// - List Attachments { get; } + List GetAttachments(); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0a91989..f5c72e1 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -114,10 +114,13 @@ namespace OpenSim.Region.Framework.Scenes } protected ScenePresenceAnimator m_animator; - public List Attachments - { - get { return m_attachments; } - } + /// + /// Attachments recorded on this avatar. + /// + /// + /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is + /// necessary. + /// protected List m_attachments = new List(); private Dictionary scriptedcontrols = new Dictionary(); @@ -940,15 +943,18 @@ namespace OpenSim.Region.Framework.Scenes // and it has already rezzed the attachments and started their scripts. // We do the following only for non-login agents, because their scripts // haven't started yet. - if (wasChild && Attachments != null && Attachments.Count > 0) + lock (m_attachments) { - m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); - // Resume scripts - Attachments.ForEach(delegate(SceneObjectGroup sog) + if (wasChild && m_attachments != null && m_attachments.Count > 0) { - sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); - sog.ResumeScripts(); - }); + m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); + // Resume scripts + foreach (SceneObjectGroup sog in m_attachments) + { + sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); + sog.ResumeScripts(); + } + } } // send the animations of the other presences to me @@ -3472,9 +3478,19 @@ namespace OpenSim.Region.Framework.Scenes m_attachments.Add(gobj); } } - + /// - /// Get the scene object attached to the given point. + /// Get all the presence's attachments. + /// + /// A copy of the list which contains the attachments. + public List GetAttachments() + { + lock (m_attachments) + return new List(m_attachments); + } + + /// + /// Get the scene objects attached to the given point. /// /// /// Returns an empty list if there were no attachments at the point. @@ -3521,6 +3537,15 @@ namespace OpenSim.Region.Framework.Scenes m_attachments.Remove(gobj); } + /// + /// Clear all attachments + /// + public void ClearAttachments() + { + lock (m_attachments) + m_attachments.Clear(); + } + public bool ValidateAttachments() { lock (m_attachments) -- cgit v1.1