* Add a large amount of extra locking to m_parts in SceneObjectGroup
* Should help stop any InvalidOperationExceptions caused by concurrent read/write * The extra locking should be okay, but I'm really surprised we've got away without mucho crashes due to this...0.6.0-stable
parent
f77ab46184
commit
d135dad051
|
@ -48,6 +48,10 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
private Encoding enc = Encoding.ASCII;
|
||||
|
||||
protected SceneObjectPart m_rootPart;
|
||||
|
||||
/// <summary>
|
||||
/// The constituent parts of this group
|
||||
/// </summary>
|
||||
protected Dictionary<LLUUID, SceneObjectPart> m_parts = new Dictionary<LLUUID, SceneObjectPart>();
|
||||
|
||||
protected ulong m_regionHandle;
|
||||
|
@ -389,6 +393,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
|
||||
EntityIntersection returnresult = new EntityIntersection();
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
// Temporary commented to stop compiler warning
|
||||
|
@ -420,6 +426,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnresult;
|
||||
}
|
||||
|
||||
|
@ -476,6 +483,9 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
m_rootPart.ToXml(writer);
|
||||
writer.WriteEndElement();
|
||||
writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
if (part.UUID != m_rootPart.UUID)
|
||||
|
@ -485,6 +495,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
writer.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
@ -507,6 +519,9 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
|
||||
m_rootPart.ToXml(writer);
|
||||
writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
if (part.UUID != m_rootPart.UUID)
|
||||
|
@ -514,6 +529,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
part.ToXml(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
@ -593,7 +610,12 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
{
|
||||
SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
|
||||
newPart.SetParent(this);
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
m_parts.Add(newPart.UUID, newPart);
|
||||
}
|
||||
|
||||
SetPartAsRoot(newPart);
|
||||
}
|
||||
|
||||
|
@ -685,7 +707,12 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
{
|
||||
SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
|
||||
newPart.SetParent(this);
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
m_parts.Add(newPart.UUID, newPart);
|
||||
}
|
||||
|
||||
SetPartAsNonRoot(newPart);
|
||||
}
|
||||
|
||||
|
@ -697,6 +724,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// </summary>
|
||||
public void ResetIDs()
|
||||
{
|
||||
// As this is only ever called for prims which are not currently part of the scene (and hence
|
||||
// not accessible by clients), there should be no need to lock
|
||||
List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
|
||||
m_parts.Clear();
|
||||
foreach (SceneObjectPart part in partsList)
|
||||
|
@ -753,6 +782,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// Examine this object's parts to see if they've changed sufficiently to warrant an update
|
||||
/// </summary>
|
||||
public override void Update()
|
||||
{
|
||||
lock (m_parts)
|
||||
{
|
||||
if (Util.GetDistanceTo(lastPhysGroupPos, AbsolutePosition) > 0.02)
|
||||
{
|
||||
|
@ -760,6 +791,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
{
|
||||
if (part.UpdateFlag == 0) part.UpdateFlag = 1;
|
||||
}
|
||||
|
||||
lastPhysGroupPos = AbsolutePosition;
|
||||
}
|
||||
|
||||
|
@ -772,6 +804,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
{
|
||||
if (part.UpdateFlag == 0) part.UpdateFlag = 1;
|
||||
}
|
||||
|
||||
lastPhysGroupRot = GroupRotation;
|
||||
}
|
||||
|
||||
|
@ -780,22 +813,29 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
part.SendScheduledUpdates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ScheduleFullUpdateToAvatar(ScenePresence presence)
|
||||
{
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
part.AddFullUpdateToAvatar(presence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
|
||||
{
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
part.AddTerseUpdateToAvatar(presence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Schedule a full update for every part in this object
|
||||
|
@ -803,11 +843,15 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
public void ScheduleGroupForFullUpdate()
|
||||
{
|
||||
HasGroupChanged = true;
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
part.ScheduleFullUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -815,11 +859,15 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
public void ScheduleGroupForTerseUpdate()
|
||||
{
|
||||
HasGroupChanged = true;
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
part.ScheduleTerseUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -827,11 +875,15 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
public void SendGroupFullUpdate()
|
||||
{
|
||||
HasGroupChanged = true;
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
part.SendFullUpdateToAllClients();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void QueueForUpdateCheck()
|
||||
{
|
||||
|
@ -844,11 +896,15 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
public void SendGroupTerseUpdate()
|
||||
{
|
||||
HasGroupChanged = true;
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
part.SendTerseUpdateToAllClients();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -860,6 +916,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// <param name="linknum"></param>
|
||||
/// <returns>null if no child part with that linknum or child part</returns>
|
||||
public SceneObjectPart GetLinkNumPart(int linknum)
|
||||
{
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
|
@ -868,6 +926,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
return part;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -892,6 +952,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// <param name="localID"></param>
|
||||
/// <returns>null if a child part with the local ID was not found</returns>
|
||||
public SceneObjectPart GetChildPart(uint localID)
|
||||
{
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
|
@ -900,6 +962,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
return part;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -925,6 +989,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// <param name="localID"></param>
|
||||
/// <returns></returns>
|
||||
public bool HasChildPrim(uint localID)
|
||||
{
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
|
@ -933,6 +999,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -988,7 +1055,11 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
|
||||
linkPart.LinkNum = m_parts.Count;
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
m_parts.Add(linkPart.UUID, linkPart);
|
||||
}
|
||||
|
||||
linkPart.SetParent(this);
|
||||
|
||||
//if (linkPart.PhysActor != null)
|
||||
|
@ -1038,7 +1109,11 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
LLQuaternion worldRot = linkPart.GetWorldRotation();
|
||||
|
||||
// Remove the part from this object
|
||||
lock (m_parts)
|
||||
{
|
||||
m_parts.Remove(linkPart.UUID);
|
||||
}
|
||||
|
||||
linkPart.ParentID = 0;
|
||||
|
||||
if (linkPart.PhysActor != null)
|
||||
|
@ -1121,7 +1196,11 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
part.SetParent(this);
|
||||
part.ParentID = m_rootPart.LocalId;
|
||||
part.LinkNum = m_parts.Count;
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
m_parts.Add(part.UUID, part);
|
||||
}
|
||||
|
||||
Vector3 axiomOldPos = new Vector3(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z);
|
||||
axiomOldPos = oldGroupRotation*axiomOldPos;
|
||||
|
@ -1297,6 +1376,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
if (part != null)
|
||||
{
|
||||
// If we have children
|
||||
lock (m_parts)
|
||||
{
|
||||
if (m_parts.Count > 1)
|
||||
{
|
||||
foreach (SceneObjectPart parts in m_parts.Values)
|
||||
|
@ -1310,6 +1391,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data)
|
||||
{
|
||||
|
@ -1465,6 +1547,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
diff.Y = axDiff.y;
|
||||
diff.Z = axDiff.z;
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart obPart in m_parts.Values)
|
||||
{
|
||||
if (obPart.UUID != m_rootPart.UUID)
|
||||
|
@ -1472,6 +1556,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
obPart.OffsetPosition = obPart.OffsetPosition + diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AbsolutePosition = newPos;
|
||||
ScheduleGroupForTerseUpdate();
|
||||
}
|
||||
|
@ -1562,6 +1648,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
|
||||
}
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart prim in m_parts.Values)
|
||||
{
|
||||
if (prim.UUID != m_rootPart.UUID)
|
||||
|
@ -1579,6 +1667,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
prim.ScheduleTerseUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_rootPart.ScheduleTerseUpdate();
|
||||
}
|
||||
|
||||
|
@ -1692,16 +1782,21 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
#endregion
|
||||
|
||||
public override void UpdateMovement()
|
||||
{
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
part.UpdateMovement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float GetTimeDilation()
|
||||
{
|
||||
return m_scene.TimeDilation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Added as a way for the storage provider to reset the scene,
|
||||
/// most likely a better way to do this sort of thing but for now...
|
||||
|
@ -1719,12 +1814,17 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// <param name="part"></param>
|
||||
public void AddPart(SceneObjectPart part)
|
||||
{
|
||||
lock (m_parts) {
|
||||
lock (m_parts)
|
||||
{
|
||||
part.SetParent(this);
|
||||
part.LinkNum = m_parts.Count;
|
||||
try {
|
||||
|
||||
try
|
||||
{
|
||||
m_parts.Add(part.UUID, part);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("Failed to add scened object part", e);
|
||||
}
|
||||
}
|
||||
|
@ -1734,6 +1834,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
///
|
||||
/// </summary>
|
||||
public void UpdateParentIDs()
|
||||
{
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
|
@ -1743,14 +1845,18 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RegenerateFullIDs()
|
||||
{
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
part.UUID = LLUUID.Random();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetChildPrimPhysicsPositions()
|
||||
{
|
||||
|
@ -1803,6 +1909,9 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
public void DeleteGroup()
|
||||
{
|
||||
DetachFromBackup(this);
|
||||
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
List<ScenePresence> avatars = GetScenePresences();
|
||||
|
@ -1817,6 +1926,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete all the parts in this group.
|
||||
|
@ -1829,11 +1939,11 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
{
|
||||
part.StopScripts();
|
||||
}
|
||||
}
|
||||
|
||||
m_rootPart = null;
|
||||
m_parts.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void AddScriptLPS(int count)
|
||||
{
|
||||
|
@ -1857,10 +1967,10 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
}
|
||||
|
||||
public void ApplyPhysics(bool m_physicalPrim)
|
||||
{
|
||||
if (m_parts.Count > 1)
|
||||
{
|
||||
lock (m_parts)
|
||||
{
|
||||
if (m_parts.Count > 1)
|
||||
{
|
||||
m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
|
@ -1874,12 +1984,12 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetOwnerId(LLUUID userId)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue