Lock the attachments dict so it doesn't get out of sync when iterating

avinationmerge
Melanie 2010-12-06 17:40:07 +01:00
parent 4b979362e9
commit b1a5c03985
1 changed files with 59 additions and 35 deletions

View File

@ -414,27 +414,36 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
public List<AvatarAttachment> GetAttachments() public List<AvatarAttachment> GetAttachments()
{ {
List<AvatarAttachment> alist = new List<AvatarAttachment>(); lock (m_attachments)
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
{ {
foreach (AvatarAttachment attach in kvp.Value) List<AvatarAttachment> alist = new List<AvatarAttachment>();
alist.Add(new AvatarAttachment(attach)); foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
} {
foreach (AvatarAttachment attach in kvp.Value)
alist.Add(new AvatarAttachment(attach));
}
return alist; return alist;
}
} }
internal void AppendAttachment(AvatarAttachment attach) internal void AppendAttachment(AvatarAttachment attach)
{ {
if (! m_attachments.ContainsKey(attach.AttachPoint)) lock (m_attachments)
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>(); {
m_attachments[attach.AttachPoint].Add(attach); if (!m_attachments.ContainsKey(attach.AttachPoint))
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
m_attachments[attach.AttachPoint].Add(attach);
}
} }
internal void ReplaceAttachment(AvatarAttachment attach) internal void ReplaceAttachment(AvatarAttachment attach)
{ {
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>(); lock (m_attachments)
m_attachments[attach.AttachPoint].Add(attach); {
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
m_attachments[attach.AttachPoint].Add(attach);
}
} }
/// <summary> /// <summary>
@ -450,9 +459,12 @@ namespace OpenSim.Framework
if (item == UUID.Zero) if (item == UUID.Zero)
{ {
if (m_attachments.ContainsKey(attachpoint)) lock (m_attachments)
m_attachments.Remove(attachpoint); {
return; if (m_attachments.ContainsKey(attachpoint))
m_attachments.Remove(attachpoint);
return;
}
} }
// check if this is an append or a replace, 0x80 marks it as an append // check if this is an append or a replace, 0x80 marks it as an append
@ -470,37 +482,46 @@ namespace OpenSim.Framework
public int GetAttachpoint(UUID itemID) public int GetAttachpoint(UUID itemID)
{ {
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) lock (m_attachments)
{ {
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; }); foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
if (index >= 0) {
return kvp.Key; int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
} if (index >= 0)
return kvp.Key;
}
return 0; return 0;
}
} }
public void DetachAttachment(UUID itemID) public void DetachAttachment(UUID itemID)
{ {
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) lock (m_attachments)
{ {
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; }); foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
if (index >= 0)
{ {
// Remove it from the list of attachments at that attach point int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
m_attachments[kvp.Key].RemoveAt(index); if (index >= 0)
{
// Remove it from the list of attachments at that attach point
m_attachments[kvp.Key].RemoveAt(index);
// And remove the list if there are no more attachments here // And remove the list if there are no more attachments here
if (m_attachments[kvp.Key].Count == 0) if (m_attachments[kvp.Key].Count == 0)
m_attachments.Remove(kvp.Key); m_attachments.Remove(kvp.Key);
return; return;
}
} }
} }
} }
public void ClearAttachments() public void ClearAttachments()
{ {
m_attachments.Clear(); lock (m_attachments)
{
m_attachments.Clear();
}
} }
#region Packing Functions #region Packing Functions
@ -537,11 +558,14 @@ namespace OpenSim.Framework
OSDBinary visualparams = new OSDBinary(m_visualparams); OSDBinary visualparams = new OSDBinary(m_visualparams);
data["visualparams"] = visualparams; data["visualparams"] = visualparams;
// Attachments lock (m_attachments)
OSDArray attachs = new OSDArray(m_attachments.Count); {
foreach (AvatarAttachment attach in GetAttachments()) // Attachments
attachs.Add(attach.Pack()); OSDArray attachs = new OSDArray(m_attachments.Count);
data["attachments"] = attachs; foreach (AvatarAttachment attach in GetAttachments())
attachs.Add(attach.Pack());
data["attachments"] = attachs;
}
return data; return data;
} }