Convert multiple lock()s which directly hinder script performance in linksets to ReaderWriterLockSlim.
parent
8bbb88ea4e
commit
9888f95068
|
@ -98,6 +98,66 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
private bool m_hasGroupChanged = false;
|
private bool m_hasGroupChanged = false;
|
||||||
private long timeFirstChanged;
|
private long timeFirstChanged;
|
||||||
private long timeLastChanged;
|
private long timeLastChanged;
|
||||||
|
private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
|
||||||
|
|
||||||
|
public void lockPartsForRead(bool locked)
|
||||||
|
{
|
||||||
|
if (locked)
|
||||||
|
{
|
||||||
|
if (m_partsLock.RecursiveReadCount > 0)
|
||||||
|
{
|
||||||
|
m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
|
||||||
|
m_partsLock.ExitReadLock();
|
||||||
|
}
|
||||||
|
if (m_partsLock.RecursiveWriteCount > 0)
|
||||||
|
{
|
||||||
|
m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed.");
|
||||||
|
m_partsLock.ExitWriteLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!m_partsLock.TryEnterReadLock(60000))
|
||||||
|
{
|
||||||
|
m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire READ lock of m_parts in SceneObjectGroup. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||||
|
if (m_partsLock.IsWriteLockHeld)
|
||||||
|
{
|
||||||
|
m_partsLock = new System.Threading.ReaderWriterLockSlim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_partsLock.ExitReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void lockPartsForWrite(bool locked)
|
||||||
|
{
|
||||||
|
if (locked)
|
||||||
|
{
|
||||||
|
if (m_partsLock.RecursiveReadCount > 0)
|
||||||
|
{
|
||||||
|
m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
|
||||||
|
m_partsLock.ExitReadLock();
|
||||||
|
}
|
||||||
|
if (m_partsLock.RecursiveWriteCount > 0)
|
||||||
|
{
|
||||||
|
m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
|
||||||
|
m_partsLock.ExitWriteLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!m_partsLock.TryEnterWriteLock(60000))
|
||||||
|
{
|
||||||
|
m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||||
|
if (m_partsLock.IsWriteLockHeld)
|
||||||
|
{
|
||||||
|
m_partsLock = new System.Threading.ReaderWriterLockSlim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_partsLock.ExitWriteLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool HasGroupChanged
|
public bool HasGroupChanged
|
||||||
{
|
{
|
||||||
|
@ -243,13 +303,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
m_regionHandle = value;
|
m_regionHandle = value;
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
part.RegionHandle = m_regionHandle;
|
part.RegionHandle = m_regionHandle;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,13 +338,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
|
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
part.GroupPosition = val;
|
part.GroupPosition = val;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
//if (m_rootPart.PhysActor != null)
|
//if (m_rootPart.PhysActor != null)
|
||||||
//{
|
//{
|
||||||
|
@ -432,13 +498,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public void SetFromItemID(UUID AssetId)
|
public void SetFromItemID(UUID AssetId)
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
part.FromItemID = AssetId;
|
part.FromItemID = AssetId;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UUID GetFromItemID()
|
public UUID GetFromItemID()
|
||||||
|
@ -505,10 +574,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Vector3 maxScale = Vector3.Zero;
|
Vector3 maxScale = Vector3.Zero;
|
||||||
Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
|
Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
Vector3 partscale = part.Scale;
|
Vector3 partscale = part.Scale;
|
||||||
Vector3 partoffset = part.OffsetPosition;
|
Vector3 partoffset = part.OffsetPosition;
|
||||||
|
|
||||||
|
@ -519,8 +589,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
|
maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
|
||||||
maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
|
maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
|
||||||
maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
|
maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
|
finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
|
||||||
finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
|
finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
|
||||||
finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
|
finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
|
||||||
|
@ -536,10 +609,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
EntityIntersection result = new EntityIntersection();
|
EntityIntersection result = new EntityIntersection();
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Temporary commented to stop compiler warning
|
// Temporary commented to stop compiler warning
|
||||||
//Vector3 partPosition =
|
//Vector3 partPosition =
|
||||||
// new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
|
// new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
|
||||||
|
@ -567,8 +641,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
result.distance = inter.distance;
|
result.distance = inter.distance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,10 +657,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
|
public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
|
||||||
{
|
{
|
||||||
float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
|
float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
Vector3 worldPos = part.GetWorldPosition();
|
Vector3 worldPos = part.GetWorldPosition();
|
||||||
Vector3 offset = worldPos - AbsolutePosition;
|
Vector3 offset = worldPos - AbsolutePosition;
|
||||||
Quaternion worldRot;
|
Quaternion worldRot;
|
||||||
|
@ -643,6 +720,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
|
backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
|
||||||
backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
|
backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
|
//m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
|
||||||
//m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
|
//m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
|
||||||
//m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
|
//m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
|
||||||
|
@ -814,6 +893,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
minZ = backBottomLeft.Z;
|
minZ = backBottomLeft.Z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
|
Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
|
||||||
|
|
||||||
|
@ -842,17 +922,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Dictionary<UUID,string> states = new Dictionary<UUID,string>();
|
Dictionary<UUID,string> states = new Dictionary<UUID,string>();
|
||||||
|
|
||||||
// Capture script state while holding the lock
|
// Capture script state while holding the lock
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
|
Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
|
||||||
foreach (UUID itemid in pstates.Keys)
|
foreach (UUID itemid in pstates.Keys)
|
||||||
{
|
{
|
||||||
states.Add(itemid, pstates[itemid]);
|
states.Add(itemid, pstates[itemid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
if (states.Count > 0)
|
if (states.Count > 0)
|
||||||
{
|
{
|
||||||
|
@ -1014,13 +1097,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public override void UpdateMovement()
|
public override void UpdateMovement()
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
part.UpdateMovement();
|
part.UpdateMovement();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ushort GetTimeDilation()
|
public ushort GetTimeDilation()
|
||||||
|
@ -1064,7 +1150,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="part"></param>
|
/// <param name="part"></param>
|
||||||
public void AddPart(SceneObjectPart part)
|
public void AddPart(SceneObjectPart part)
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForWrite(true);
|
||||||
{
|
{
|
||||||
part.SetParent(this);
|
part.SetParent(this);
|
||||||
m_parts.Add(part.UUID, part);
|
m_parts.Add(part.UUID, part);
|
||||||
|
@ -1074,6 +1160,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (part.LinkNum == 2 && RootPart != null)
|
if (part.LinkNum == 2 && RootPart != null)
|
||||||
RootPart.LinkNum = 1;
|
RootPart.LinkNum = 1;
|
||||||
}
|
}
|
||||||
|
lockPartsForWrite(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1081,28 +1168,33 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdateParentIDs()
|
private void UpdateParentIDs()
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (part.UUID != m_rootPart.UUID)
|
if (part.UUID != m_rootPart.UUID)
|
||||||
{
|
{
|
||||||
part.ParentID = m_rootPart.LocalId;
|
part.ParentID = m_rootPart.LocalId;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegenerateFullIDs()
|
public void RegenerateFullIDs()
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
part.UUID = UUID.Random();
|
part.UUID = UUID.Random();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper provided for parts.
|
// helper provided for parts.
|
||||||
|
@ -1183,29 +1275,33 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
DetachFromBackup();
|
DetachFromBackup();
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
|
List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
|
foreach (SceneObjectPart part in values)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
{
|
|
||||||
// part.Inventory.RemoveScriptInstances();
|
// part.Inventory.RemoveScriptInstances();
|
||||||
|
|
||||||
ScenePresence[] avatars = Scene.GetScenePresences();
|
ScenePresence[] avatars = Scene.GetScenePresences();
|
||||||
for (int i = 0; i < avatars.Length; i++)
|
for (int i = 0; i < avatars.Length; i++)
|
||||||
|
{
|
||||||
|
if (avatars[i].ParentID == LocalId)
|
||||||
{
|
{
|
||||||
if (avatars[i].ParentID == LocalId)
|
avatars[i].StandUp();
|
||||||
{
|
}
|
||||||
avatars[i].StandUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!silent)
|
if (!silent)
|
||||||
{
|
{
|
||||||
part.UpdateFlag = 0;
|
part.UpdateFlag = 0;
|
||||||
if (part == m_rootPart)
|
if (part == m_rootPart)
|
||||||
avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
|
avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddScriptLPS(int count)
|
public void AddScriptLPS(int count)
|
||||||
|
@ -1230,17 +1326,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
scriptEvents aggregateScriptEvents=0;
|
scriptEvents aggregateScriptEvents=0;
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (part == null)
|
if (part == null)
|
||||||
continue;
|
continue;
|
||||||
if (part != RootPart)
|
if (part != RootPart)
|
||||||
part.ObjectFlags = objectflagupdate;
|
part.ObjectFlags = objectflagupdate;
|
||||||
aggregateScriptEvents |= part.AggregateScriptEvents;
|
aggregateScriptEvents |= part.AggregateScriptEvents;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
|
m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
|
||||||
m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
|
m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
|
||||||
|
@ -1273,42 +1372,52 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="m_physicalPrim"></param>
|
/// <param name="m_physicalPrim"></param>
|
||||||
public void ApplyPhysics(bool m_physicalPrim)
|
public void ApplyPhysics(bool m_physicalPrim)
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
|
|
||||||
|
if (m_parts.Count > 1)
|
||||||
{
|
{
|
||||||
if (m_parts.Count > 1)
|
List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
|
||||||
|
lockPartsForRead(false);
|
||||||
|
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
|
||||||
|
foreach (SceneObjectPart part in values)
|
||||||
{
|
{
|
||||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
|
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
if (part.LocalId != m_rootPart.LocalId)
|
||||||
{
|
{
|
||||||
if (part.LocalId != m_rootPart.LocalId)
|
part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
|
||||||
{
|
|
||||||
part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hack to get the physics scene geometries in the right spot
|
|
||||||
ResetChildPrimPhysicsPositions();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
|
|
||||||
}
|
}
|
||||||
|
// Hack to get the physics scene geometries in the right spot
|
||||||
|
ResetChildPrimPhysicsPositions();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lockPartsForRead(false);
|
||||||
|
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetOwnerId(UUID userId)
|
public void SetOwnerId(UUID userId)
|
||||||
{
|
{
|
||||||
ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; });
|
ForEachPart(delegate(SceneObjectPart part)
|
||||||
|
{
|
||||||
|
|
||||||
|
part.OwnerID = userId;
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ForEachPart(Action<SceneObjectPart> whatToDo)
|
public void ForEachPart(Action<SceneObjectPart> whatToDo)
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
|
List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
|
||||||
|
lockPartsForRead(false);
|
||||||
|
foreach (SceneObjectPart part in values)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
{
|
whatToDo(part);
|
||||||
whatToDo(part);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1407,14 +1516,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
|
SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (part != RootPart)
|
if (part != RootPart)
|
||||||
SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
|
SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1509,10 +1621,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
List<SceneObjectPart> partList;
|
List<SceneObjectPart> partList;
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
|
||||||
partList = new List<SceneObjectPart>(m_parts.Values);
|
partList = new List<SceneObjectPart>(m_parts.Values);
|
||||||
}
|
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
|
partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
|
||||||
{
|
{
|
||||||
|
@ -1835,10 +1948,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
|
SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
|
||||||
newPart.SetParent(this);
|
newPart.SetParent(this);
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForWrite(true);
|
||||||
{
|
{
|
||||||
m_parts.Add(newPart.UUID, newPart);
|
m_parts.Add(newPart.UUID, newPart);
|
||||||
}
|
}
|
||||||
|
lockPartsForWrite(false);
|
||||||
|
|
||||||
SetPartAsNonRoot(newPart);
|
SetPartAsNonRoot(newPart);
|
||||||
|
|
||||||
|
@ -1901,7 +2015,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
//if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
|
//if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
|
bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
|
||||||
|
|
||||||
|
@ -1919,34 +2033,43 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
part.SendScheduledUpdates();
|
part.SendScheduledUpdates();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScheduleFullUpdateToAvatar(ScenePresence presence)
|
public void ScheduleFullUpdateToAvatar(ScenePresence presence)
|
||||||
{
|
{
|
||||||
RootPart.AddFullUpdateToAvatar(presence);
|
RootPart.AddFullUpdateToAvatar(presence);
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (part != RootPart)
|
if (part != RootPart)
|
||||||
part.AddFullUpdateToAvatar(presence);
|
part.AddFullUpdateToAvatar(presence);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
|
public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
part.AddTerseUpdateToAvatar(presence);
|
part.AddTerseUpdateToAvatar(presence);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1957,14 +2080,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
checkAtTargets();
|
checkAtTargets();
|
||||||
RootPart.ScheduleFullUpdate();
|
RootPart.ScheduleFullUpdate();
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (part != RootPart)
|
if (part != RootPart)
|
||||||
part.ScheduleFullUpdate();
|
part.ScheduleFullUpdate();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1972,13 +2098,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ScheduleGroupForTerseUpdate()
|
public void ScheduleGroupForTerseUpdate()
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
part.ScheduleTerseUpdate();
|
part.ScheduleTerseUpdate();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1991,14 +2120,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
RootPart.SendFullUpdateToAllClients();
|
RootPart.SendFullUpdateToAllClients();
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (part != RootPart)
|
if (part != RootPart)
|
||||||
part.SendFullUpdateToAllClients();
|
part.SendFullUpdateToAllClients();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -2029,14 +2161,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
if (IsDeleted)
|
if (IsDeleted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
part.SendTerseUpdateToAllClients();
|
part.SendTerseUpdateToAllClients();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -2050,16 +2183,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <returns>null if no child part with that linknum or child part</returns>
|
/// <returns>null if no child part with that linknum or child part</returns>
|
||||||
public SceneObjectPart GetLinkNumPart(int linknum)
|
public SceneObjectPart GetLinkNumPart(int linknum)
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
if (part.LinkNum == linknum)
|
if (part.LinkNum == linknum)
|
||||||
{
|
{
|
||||||
|
lockPartsForRead(false);
|
||||||
return part;
|
return part;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -2087,17 +2222,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public SceneObjectPart GetChildPart(uint localID)
|
public SceneObjectPart GetChildPart(uint localID)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("Entered looking for {0}", localID);
|
//m_log.DebugFormat("Entered looking for {0}", localID);
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("Found {0}", part.LocalId);
|
//m_log.DebugFormat("Found {0}", part.LocalId);
|
||||||
if (part.LocalId == localID)
|
if (part.LocalId == localID)
|
||||||
{
|
{
|
||||||
|
lockPartsForRead(false);
|
||||||
return part;
|
return part;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -2127,17 +2264,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public bool HasChildPrim(uint localID)
|
public bool HasChildPrim(uint localID)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
|
//m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("Found {0}", part.LocalId);
|
//m_log.DebugFormat("Found {0}", part.LocalId);
|
||||||
if (part.LocalId == localID)
|
if (part.LocalId == localID)
|
||||||
{
|
{
|
||||||
|
lockPartsForRead(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2187,53 +2326,57 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (m_rootPart.LinkNum == 0)
|
if (m_rootPart.LinkNum == 0)
|
||||||
m_rootPart.LinkNum = 1;
|
m_rootPart.LinkNum = 1;
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForWrite(true);
|
||||||
|
|
||||||
|
m_parts.Add(linkPart.UUID, linkPart);
|
||||||
|
|
||||||
|
lockPartsForWrite(false);
|
||||||
|
|
||||||
|
// Insert in terms of link numbers, the new links
|
||||||
|
// before the current ones (with the exception of
|
||||||
|
// the root prim. Shuffle the old ones up
|
||||||
|
lockPartsForRead(true);
|
||||||
|
foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
|
||||||
{
|
{
|
||||||
m_parts.Add(linkPart.UUID, linkPart);
|
if (kvp.Value.LinkNum != 1)
|
||||||
|
|
||||||
// Insert in terms of link numbers, the new links
|
|
||||||
// before the current ones (with the exception of
|
|
||||||
// the root prim. Shuffle the old ones up
|
|
||||||
foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
|
|
||||||
{
|
{
|
||||||
if (kvp.Value.LinkNum != 1)
|
// Don't update root prim link number
|
||||||
{
|
kvp.Value.LinkNum += objectGroup.PrimCount;
|
||||||
// Don't update root prim link number
|
|
||||||
kvp.Value.LinkNum += objectGroup.PrimCount;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
linkPart.LinkNum = 2;
|
linkPart.LinkNum = 2;
|
||||||
|
|
||||||
linkPart.SetParent(this);
|
linkPart.SetParent(this);
|
||||||
linkPart.AddFlag(PrimFlags.CreateSelected);
|
linkPart.AddFlag(PrimFlags.CreateSelected);
|
||||||
|
|
||||||
//if (linkPart.PhysActor != null)
|
//if (linkPart.PhysActor != null)
|
||||||
//{
|
//{
|
||||||
// m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
|
// m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
|
||||||
|
|
||||||
//linkPart.PhysActor = null;
|
//linkPart.PhysActor = null;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//TODO: rest of parts
|
//TODO: rest of parts
|
||||||
int linkNum = 3;
|
int linkNum = 3;
|
||||||
foreach (SceneObjectPart part in objectGroup.Children.Values)
|
foreach (SceneObjectPart part in objectGroup.Children.Values)
|
||||||
|
{
|
||||||
|
if (part.UUID != objectGroup.m_rootPart.UUID)
|
||||||
{
|
{
|
||||||
if (part.UUID != objectGroup.m_rootPart.UUID)
|
LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
|
||||||
{
|
|
||||||
LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
|
|
||||||
}
|
|
||||||
part.ClearUndoState();
|
|
||||||
}
|
}
|
||||||
|
part.ClearUndoState();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_scene.UnlinkSceneObject(objectGroup.UUID, true);
|
m_scene.UnlinkSceneObject(objectGroup.UUID, true);
|
||||||
objectGroup.m_isDeleted = true;
|
objectGroup.m_isDeleted = true;
|
||||||
|
|
||||||
|
objectGroup.lockPartsForWrite(true);
|
||||||
|
|
||||||
lock (objectGroup.m_parts)
|
objectGroup.m_parts.Clear();
|
||||||
{
|
|
||||||
objectGroup.m_parts.Clear();
|
objectGroup.lockPartsForWrite(false);
|
||||||
}
|
|
||||||
|
|
||||||
// Can't do this yet since backup still makes use of the root part without any synchronization
|
// Can't do this yet since backup still makes use of the root part without any synchronization
|
||||||
// objectGroup.m_rootPart = null;
|
// objectGroup.m_rootPart = null;
|
||||||
|
@ -2292,11 +2435,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Quaternion worldRot = linkPart.GetWorldRotation();
|
Quaternion worldRot = linkPart.GetWorldRotation();
|
||||||
|
|
||||||
// Remove the part from this object
|
// Remove the part from this object
|
||||||
lock (m_parts)
|
lockPartsForWrite(true);
|
||||||
{
|
{
|
||||||
m_parts.Remove(linkPart.UUID);
|
m_parts.Remove(linkPart.UUID);
|
||||||
}
|
}
|
||||||
|
lockPartsForWrite(false);
|
||||||
|
lockPartsForRead(true);
|
||||||
if (m_parts.Count == 1 && RootPart != null) //Single prim is left
|
if (m_parts.Count == 1 && RootPart != null) //Single prim is left
|
||||||
RootPart.LinkNum = 0;
|
RootPart.LinkNum = 0;
|
||||||
else
|
else
|
||||||
|
@ -2307,6 +2451,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
p.LinkNum--;
|
p.LinkNum--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
linkPart.ParentID = 0;
|
linkPart.ParentID = 0;
|
||||||
linkPart.LinkNum = 0;
|
linkPart.LinkNum = 0;
|
||||||
|
@ -2624,22 +2769,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (selectionPart != null)
|
if (selectionPart != null)
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
|
List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
|
||||||
|
lockPartsForRead(false);
|
||||||
|
foreach (SceneObjectPart part in parts)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
|
||||||
{
|
{
|
||||||
if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
|
UsePhysics = false; // Reset physics
|
||||||
{
|
break;
|
||||||
UsePhysics = false; // Reset physics
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
{
|
|
||||||
part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (SceneObjectPart part in parts)
|
||||||
|
{
|
||||||
|
part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2863,7 +3009,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
prevScale.Z *= z;
|
prevScale.Z *= z;
|
||||||
part.Resize(prevScale);
|
part.Resize(prevScale);
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart obPart in m_parts.Values)
|
foreach (SceneObjectPart obPart in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
@ -2882,6 +3028,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
if (part.PhysActor != null)
|
if (part.PhysActor != null)
|
||||||
{
|
{
|
||||||
|
@ -2962,7 +3109,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
axDiff *= Quaternion.Inverse(partRotation);
|
axDiff *= Quaternion.Inverse(partRotation);
|
||||||
diff = axDiff;
|
diff = axDiff;
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart obPart in m_parts.Values)
|
foreach (SceneObjectPart obPart in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
@ -2972,6 +3119,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
AbsolutePosition = newPos;
|
AbsolutePosition = newPos;
|
||||||
|
|
||||||
|
@ -3089,7 +3237,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
|
m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart prim in m_parts.Values)
|
foreach (SceneObjectPart prim in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
@ -3107,6 +3255,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
m_rootPart.ScheduleTerseUpdate();
|
m_rootPart.ScheduleTerseUpdate();
|
||||||
}
|
}
|
||||||
|
@ -3205,7 +3354,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (atTargets.Count > 0)
|
if (atTargets.Count > 0)
|
||||||
{
|
{
|
||||||
uint[] localids = new uint[0];
|
uint[] localids = new uint[0];
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
localids = new uint[m_parts.Count];
|
localids = new uint[m_parts.Count];
|
||||||
int cntr = 0;
|
int cntr = 0;
|
||||||
|
@ -3215,6 +3364,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
cntr++;
|
cntr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
for (int ctr = 0; ctr < localids.Length; ctr++)
|
for (int ctr = 0; ctr < localids.Length; ctr++)
|
||||||
{
|
{
|
||||||
|
@ -3233,7 +3383,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
//trigger not_at_target
|
//trigger not_at_target
|
||||||
uint[] localids = new uint[0];
|
uint[] localids = new uint[0];
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
localids = new uint[m_parts.Count];
|
localids = new uint[m_parts.Count];
|
||||||
int cntr = 0;
|
int cntr = 0;
|
||||||
|
@ -3243,7 +3393,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
cntr++;
|
cntr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
|
|
||||||
for (int ctr = 0; ctr < localids.Length; ctr++)
|
for (int ctr = 0; ctr < localids.Length; ctr++)
|
||||||
{
|
{
|
||||||
m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
|
m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
|
||||||
|
@ -3256,19 +3407,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public float GetMass()
|
public float GetMass()
|
||||||
{
|
{
|
||||||
float retmass = 0f;
|
float retmass = 0f;
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
retmass += part.GetMass();
|
retmass += part.GetMass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
return retmass;
|
return retmass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CheckSculptAndLoad()
|
public void CheckSculptAndLoad()
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
if (!IsDeleted)
|
if (!IsDeleted)
|
||||||
{
|
{
|
||||||
|
@ -3293,6 +3445,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void AssetReceived(string id, Object sender, AssetBase asset)
|
protected void AssetReceived(string id, Object sender, AssetBase asset)
|
||||||
|
@ -3313,7 +3466,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="client"></param>
|
/// <param name="client"></param>
|
||||||
public void SetGroup(UUID GroupID, IClientAPI client)
|
public void SetGroup(UUID GroupID, IClientAPI client)
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
@ -3323,7 +3476,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
HasGroupChanged = true;
|
HasGroupChanged = true;
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
ScheduleGroupForFullUpdate();
|
ScheduleGroupForFullUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3342,11 +3495,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public void SetAttachmentPoint(byte point)
|
public void SetAttachmentPoint(byte point)
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
lockPartsForRead(true);
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
part.SetAttachmentPoint(point);
|
part.SetAttachmentPoint(point);
|
||||||
}
|
}
|
||||||
|
lockPartsForRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region ISceneObject
|
#region ISceneObject
|
||||||
|
|
|
@ -2950,8 +2950,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return m_host.OwnerID.ToString();
|
return m_host.OwnerID.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DebuggerNonUserCode]
|
||||||
public void llInstantMessage(string user, string message)
|
public void llInstantMessage(string user, string message)
|
||||||
{
|
{
|
||||||
|
UUID result;
|
||||||
|
if (!UUID.TryParse(user, out result))
|
||||||
|
{
|
||||||
|
throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
// We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
|
// We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
|
||||||
|
@ -2966,7 +2975,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
UUID friendTransactionID = UUID.Random();
|
UUID friendTransactionID = UUID.Random();
|
||||||
|
|
||||||
//m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
|
//m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
|
||||||
|
|
||||||
GridInstantMessage msg = new GridInstantMessage();
|
GridInstantMessage msg = new GridInstantMessage();
|
||||||
msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
|
msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
|
||||||
msg.toAgentID = new Guid(user); // toAgentID.Guid;
|
msg.toAgentID = new Guid(user); // toAgentID.Guid;
|
||||||
|
|
|
@ -101,6 +101,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
private Dictionary<UUID, IScriptInstance> m_Scripts =
|
private Dictionary<UUID, IScriptInstance> m_Scripts =
|
||||||
new Dictionary<UUID, IScriptInstance>();
|
new Dictionary<UUID, IScriptInstance>();
|
||||||
|
|
||||||
|
private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
|
||||||
|
|
||||||
// Maps the asset ID to the assembly
|
// Maps the asset ID to the assembly
|
||||||
|
|
||||||
private Dictionary<UUID, string> m_Assemblies =
|
private Dictionary<UUID, string> m_Assemblies =
|
||||||
|
@ -122,6 +124,65 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue();
|
private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue();
|
||||||
IWorkItemResult m_CurrentCompile = null;
|
IWorkItemResult m_CurrentCompile = null;
|
||||||
|
|
||||||
|
private void lockScriptsForRead(bool locked)
|
||||||
|
{
|
||||||
|
if (locked)
|
||||||
|
{
|
||||||
|
if (m_scriptsLock.RecursiveReadCount > 0)
|
||||||
|
{
|
||||||
|
m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
|
||||||
|
m_scriptsLock.ExitReadLock();
|
||||||
|
}
|
||||||
|
if (m_scriptsLock.RecursiveWriteCount > 0)
|
||||||
|
{
|
||||||
|
m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
|
||||||
|
m_scriptsLock.ExitWriteLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!m_scriptsLock.TryEnterReadLock(60000))
|
||||||
|
{
|
||||||
|
m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||||
|
if (m_scriptsLock.IsWriteLockHeld)
|
||||||
|
{
|
||||||
|
m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_scriptsLock.ExitReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void lockScriptsForWrite(bool locked)
|
||||||
|
{
|
||||||
|
if (locked)
|
||||||
|
{
|
||||||
|
if (m_scriptsLock.RecursiveReadCount > 0)
|
||||||
|
{
|
||||||
|
m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
|
||||||
|
m_scriptsLock.ExitReadLock();
|
||||||
|
}
|
||||||
|
if (m_scriptsLock.RecursiveWriteCount > 0)
|
||||||
|
{
|
||||||
|
m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
|
||||||
|
m_scriptsLock.ExitWriteLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!m_scriptsLock.TryEnterWriteLock(60000))
|
||||||
|
{
|
||||||
|
m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||||
|
if (m_scriptsLock.IsWriteLockHeld)
|
||||||
|
{
|
||||||
|
m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_scriptsLock.ExitWriteLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string ScriptEngineName
|
public string ScriptEngineName
|
||||||
{
|
{
|
||||||
get { return "XEngine"; }
|
get { return "XEngine"; }
|
||||||
|
@ -261,43 +322,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
{
|
{
|
||||||
lock (m_Scripts)
|
lockScriptsForRead(true);
|
||||||
|
foreach (IScriptInstance instance in m_Scripts.Values)
|
||||||
{
|
{
|
||||||
foreach (IScriptInstance instance in m_Scripts.Values)
|
// Force a final state save
|
||||||
|
//
|
||||||
|
if (m_Assemblies.ContainsKey(instance.AssetID))
|
||||||
{
|
{
|
||||||
// Force a final state save
|
string assembly = m_Assemblies[instance.AssetID];
|
||||||
//
|
instance.SaveState(assembly);
|
||||||
if (m_Assemblies.ContainsKey(instance.AssetID))
|
}
|
||||||
{
|
|
||||||
string assembly = m_Assemblies[instance.AssetID];
|
// Clear the event queue and abort the instance thread
|
||||||
instance.SaveState(assembly);
|
//
|
||||||
}
|
instance.ClearQueue();
|
||||||
|
instance.Stop(0);
|
||||||
// Clear the event queue and abort the instance thread
|
|
||||||
//
|
// Release events, timer, etc
|
||||||
instance.ClearQueue();
|
//
|
||||||
instance.Stop(0);
|
instance.DestroyScriptInstance();
|
||||||
|
|
||||||
// Release events, timer, etc
|
// Unload scripts and app domains
|
||||||
//
|
// Must be done explicitly because they have infinite
|
||||||
instance.DestroyScriptInstance();
|
// lifetime
|
||||||
|
//
|
||||||
// Unload scripts and app domains
|
m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
|
||||||
// Must be done explicitly because they have infinite
|
if (m_DomainScripts[instance.AppDomain].Count == 0)
|
||||||
// lifetime
|
{
|
||||||
//
|
m_DomainScripts.Remove(instance.AppDomain);
|
||||||
m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
|
UnloadAppDomain(instance.AppDomain);
|
||||||
if (m_DomainScripts[instance.AppDomain].Count == 0)
|
|
||||||
{
|
|
||||||
m_DomainScripts.Remove(instance.AppDomain);
|
|
||||||
UnloadAppDomain(instance.AppDomain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
m_Scripts.Clear();
|
|
||||||
m_PrimObjects.Clear();
|
|
||||||
m_Assemblies.Clear();
|
|
||||||
m_DomainScripts.Clear();
|
|
||||||
}
|
}
|
||||||
|
lockScriptsForRead(false);
|
||||||
|
lockScriptsForWrite(true);
|
||||||
|
m_Scripts.Clear();
|
||||||
|
lockScriptsForWrite(false);
|
||||||
|
m_PrimObjects.Clear();
|
||||||
|
m_Assemblies.Clear();
|
||||||
|
m_DomainScripts.Clear();
|
||||||
|
|
||||||
lock (m_ScriptEngines)
|
lock (m_ScriptEngines)
|
||||||
{
|
{
|
||||||
m_ScriptEngines.Remove(this);
|
m_ScriptEngines.Remove(this);
|
||||||
|
@ -356,22 +419,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
|
|
||||||
List<IScriptInstance> instances = new List<IScriptInstance>();
|
List<IScriptInstance> instances = new List<IScriptInstance>();
|
||||||
|
|
||||||
lock (m_Scripts)
|
lockScriptsForRead(true);
|
||||||
{
|
foreach (IScriptInstance instance in m_Scripts.Values)
|
||||||
foreach (IScriptInstance instance in m_Scripts.Values)
|
|
||||||
instances.Add(instance);
|
instances.Add(instance);
|
||||||
}
|
lockScriptsForRead(false);
|
||||||
|
|
||||||
foreach (IScriptInstance i in instances)
|
foreach (IScriptInstance i in instances)
|
||||||
{
|
{
|
||||||
string assembly = String.Empty;
|
string assembly = String.Empty;
|
||||||
|
|
||||||
lock (m_Scripts)
|
|
||||||
{
|
|
||||||
if (!m_Assemblies.ContainsKey(i.AssetID))
|
if (!m_Assemblies.ContainsKey(i.AssetID))
|
||||||
continue;
|
continue;
|
||||||
assembly = m_Assemblies[i.AssetID];
|
assembly = m_Assemblies[i.AssetID];
|
||||||
}
|
|
||||||
|
|
||||||
i.SaveState(assembly);
|
i.SaveState(assembly);
|
||||||
}
|
}
|
||||||
|
@ -673,173 +734,184 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_Scripts)
|
|
||||||
|
|
||||||
|
ScriptInstance instance = null;
|
||||||
|
// Create the object record
|
||||||
|
lockScriptsForRead(true);
|
||||||
|
if ((!m_Scripts.ContainsKey(itemID)) ||
|
||||||
|
(m_Scripts[itemID].AssetID != assetID))
|
||||||
{
|
{
|
||||||
ScriptInstance instance = null;
|
lockScriptsForRead(false);
|
||||||
// Create the object record
|
|
||||||
|
|
||||||
if ((!m_Scripts.ContainsKey(itemID)) ||
|
UUID appDomain = assetID;
|
||||||
(m_Scripts[itemID].AssetID != assetID))
|
|
||||||
|
if (part.ParentGroup.IsAttachment)
|
||||||
|
appDomain = part.ParentGroup.RootPart.UUID;
|
||||||
|
|
||||||
|
if (!m_AppDomains.ContainsKey(appDomain))
|
||||||
{
|
{
|
||||||
UUID appDomain = assetID;
|
try
|
||||||
|
|
||||||
if (part.ParentGroup.IsAttachment)
|
|
||||||
appDomain = part.ParentGroup.RootPart.UUID;
|
|
||||||
|
|
||||||
if (!m_AppDomains.ContainsKey(appDomain))
|
|
||||||
{
|
{
|
||||||
try
|
AppDomainSetup appSetup = new AppDomainSetup();
|
||||||
{
|
// appSetup.ApplicationBase = Path.Combine(
|
||||||
AppDomainSetup appSetup = new AppDomainSetup();
|
// "ScriptEngines",
|
||||||
// appSetup.ApplicationBase = Path.Combine(
|
// m_Scene.RegionInfo.RegionID.ToString());
|
||||||
// "ScriptEngines",
|
|
||||||
// m_Scene.RegionInfo.RegionID.ToString());
|
|
||||||
|
|
||||||
Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
|
Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
|
||||||
Evidence evidence = new Evidence(baseEvidence);
|
Evidence evidence = new Evidence(baseEvidence);
|
||||||
|
|
||||||
AppDomain sandbox;
|
AppDomain sandbox;
|
||||||
if (m_AppDomainLoading)
|
if (m_AppDomainLoading)
|
||||||
sandbox = AppDomain.CreateDomain(
|
sandbox = AppDomain.CreateDomain(
|
||||||
m_Scene.RegionInfo.RegionID.ToString(),
|
m_Scene.RegionInfo.RegionID.ToString(),
|
||||||
evidence, appSetup);
|
evidence, appSetup);
|
||||||
else
|
else
|
||||||
sandbox = AppDomain.CurrentDomain;
|
sandbox = AppDomain.CurrentDomain;
|
||||||
|
|
||||||
//PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
|
|
||||||
//AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
|
|
||||||
//PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
|
|
||||||
//PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
|
|
||||||
//CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
|
|
||||||
//sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
|
|
||||||
//sandbox.SetAppDomainPolicy(sandboxPolicy);
|
|
||||||
|
|
||||||
m_AppDomains[appDomain] = sandbox;
|
|
||||||
|
|
||||||
m_AppDomains[appDomain].AssemblyResolve +=
|
//PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
|
||||||
new ResolveEventHandler(
|
//AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
|
||||||
AssemblyResolver.OnAssemblyResolve);
|
//PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
|
||||||
m_DomainScripts[appDomain] = new List<UUID>();
|
//PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
|
||||||
}
|
//CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
|
||||||
catch (Exception e)
|
//sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
|
||||||
{
|
//sandbox.SetAppDomainPolicy(sandboxPolicy);
|
||||||
m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
|
|
||||||
m_ScriptErrorMessage += "Exception creating app domain:\n";
|
m_AppDomains[appDomain] = sandbox;
|
||||||
m_ScriptFailCount++;
|
|
||||||
lock (m_AddingAssemblies)
|
m_AppDomains[appDomain].AssemblyResolve +=
|
||||||
{
|
new ResolveEventHandler(
|
||||||
m_AddingAssemblies[assembly]--;
|
AssemblyResolver.OnAssemblyResolve);
|
||||||
}
|
m_DomainScripts[appDomain] = new List<UUID>();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
m_DomainScripts[appDomain].Add(itemID);
|
catch (Exception e)
|
||||||
|
|
||||||
instance = new ScriptInstance(this, part,
|
|
||||||
itemID, assetID, assembly,
|
|
||||||
m_AppDomains[appDomain],
|
|
||||||
part.ParentGroup.RootPart.Name,
|
|
||||||
item.Name, startParam, postOnRez,
|
|
||||||
stateSource, m_MaxScriptQueue);
|
|
||||||
|
|
||||||
m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
|
|
||||||
part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
|
|
||||||
|
|
||||||
if (presence != null)
|
|
||||||
{
|
{
|
||||||
ShowScriptSaveResponse(item.OwnerID,
|
m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
|
||||||
assetID, "Compile successful", true);
|
m_ScriptErrorMessage += "Exception creating app domain:\n";
|
||||||
|
m_ScriptFailCount++;
|
||||||
|
lock (m_AddingAssemblies)
|
||||||
|
{
|
||||||
|
m_AddingAssemblies[assembly]--;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.AppDomain = appDomain;
|
|
||||||
instance.LineMap = linemap;
|
|
||||||
|
|
||||||
m_Scripts[itemID] = instance;
|
|
||||||
}
|
}
|
||||||
|
m_DomainScripts[appDomain].Add(itemID);
|
||||||
|
|
||||||
lock (m_PrimObjects)
|
instance = new ScriptInstance(this, part,
|
||||||
|
itemID, assetID, assembly,
|
||||||
|
m_AppDomains[appDomain],
|
||||||
|
part.ParentGroup.RootPart.Name,
|
||||||
|
item.Name, startParam, postOnRez,
|
||||||
|
stateSource, m_MaxScriptQueue);
|
||||||
|
|
||||||
|
m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
|
||||||
|
part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
|
||||||
|
|
||||||
|
if (presence != null)
|
||||||
{
|
{
|
||||||
if (!m_PrimObjects.ContainsKey(localID))
|
ShowScriptSaveResponse(item.OwnerID,
|
||||||
m_PrimObjects[localID] = new List<UUID>();
|
assetID, "Compile successful", true);
|
||||||
|
|
||||||
if (!m_PrimObjects[localID].Contains(itemID))
|
|
||||||
m_PrimObjects[localID].Add(itemID);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_Assemblies.ContainsKey(assetID))
|
instance.AppDomain = appDomain;
|
||||||
m_Assemblies[assetID] = assembly;
|
instance.LineMap = linemap;
|
||||||
|
lockScriptsForWrite(true);
|
||||||
lock (m_AddingAssemblies)
|
m_Scripts[itemID] = instance;
|
||||||
{
|
lockScriptsForWrite(false);
|
||||||
m_AddingAssemblies[assembly]--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instance!=null)
|
|
||||||
instance.Init();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lockScriptsForRead(false);
|
||||||
|
}
|
||||||
|
lock (m_PrimObjects)
|
||||||
|
{
|
||||||
|
if (!m_PrimObjects.ContainsKey(localID))
|
||||||
|
m_PrimObjects[localID] = new List<UUID>();
|
||||||
|
|
||||||
|
if (!m_PrimObjects[localID].Contains(itemID))
|
||||||
|
m_PrimObjects[localID].Add(itemID);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_Assemblies.ContainsKey(assetID))
|
||||||
|
m_Assemblies[assetID] = assembly;
|
||||||
|
|
||||||
|
lock (m_AddingAssemblies)
|
||||||
|
{
|
||||||
|
m_AddingAssemblies[assembly]--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance!=null)
|
||||||
|
instance.Init();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnRemoveScript(uint localID, UUID itemID)
|
public void OnRemoveScript(uint localID, UUID itemID)
|
||||||
{
|
{
|
||||||
lock (m_Scripts)
|
lockScriptsForRead(true);
|
||||||
|
// Do we even have it?
|
||||||
|
if (!m_Scripts.ContainsKey(itemID))
|
||||||
{
|
{
|
||||||
// Do we even have it?
|
lockScriptsForRead(false);
|
||||||
if (!m_Scripts.ContainsKey(itemID))
|
return;
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
|
||||||
IScriptInstance instance=m_Scripts[itemID];
|
IScriptInstance instance=m_Scripts[itemID];
|
||||||
m_Scripts.Remove(itemID);
|
lockScriptsForRead(false);
|
||||||
|
lockScriptsForWrite(true);
|
||||||
|
m_Scripts.Remove(itemID);
|
||||||
|
lockScriptsForWrite(false);
|
||||||
|
instance.ClearQueue();
|
||||||
|
instance.Stop(0);
|
||||||
|
|
||||||
instance.ClearQueue();
|
SceneObjectPart part =
|
||||||
instance.Stop(0);
|
m_Scene.GetSceneObjectPart(localID);
|
||||||
|
|
||||||
SceneObjectPart part =
|
if (part != null)
|
||||||
m_Scene.GetSceneObjectPart(localID);
|
part.RemoveScriptEvents(itemID);
|
||||||
|
|
||||||
if (part != null)
|
|
||||||
part.RemoveScriptEvents(itemID);
|
|
||||||
|
|
||||||
// bool objectRemoved = false;
|
// bool objectRemoved = false;
|
||||||
|
|
||||||
lock (m_PrimObjects)
|
lock (m_PrimObjects)
|
||||||
|
{
|
||||||
|
// Remove the script from it's prim
|
||||||
|
if (m_PrimObjects.ContainsKey(localID))
|
||||||
{
|
{
|
||||||
// Remove the script from it's prim
|
// Remove inventory item record
|
||||||
if (m_PrimObjects.ContainsKey(localID))
|
if (m_PrimObjects[localID].Contains(itemID))
|
||||||
{
|
m_PrimObjects[localID].Remove(itemID);
|
||||||
// Remove inventory item record
|
|
||||||
if (m_PrimObjects[localID].Contains(itemID))
|
|
||||||
m_PrimObjects[localID].Remove(itemID);
|
|
||||||
|
|
||||||
// If there are no more scripts, remove prim
|
// If there are no more scripts, remove prim
|
||||||
if (m_PrimObjects[localID].Count == 0)
|
if (m_PrimObjects[localID].Count == 0)
|
||||||
{
|
{
|
||||||
m_PrimObjects.Remove(localID);
|
m_PrimObjects.Remove(localID);
|
||||||
// objectRemoved = true;
|
// objectRemoved = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.RemoveState();
|
|
||||||
instance.DestroyScriptInstance();
|
|
||||||
|
|
||||||
m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
|
|
||||||
if (m_DomainScripts[instance.AppDomain].Count == 0)
|
|
||||||
{
|
|
||||||
m_DomainScripts.Remove(instance.AppDomain);
|
|
||||||
UnloadAppDomain(instance.AppDomain);
|
|
||||||
}
|
|
||||||
|
|
||||||
instance = null;
|
|
||||||
|
|
||||||
ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
|
|
||||||
if (handlerObjectRemoved != null)
|
|
||||||
handlerObjectRemoved(part.UUID);
|
|
||||||
|
|
||||||
CleanAssemblies();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instance.RemoveState();
|
||||||
|
instance.DestroyScriptInstance();
|
||||||
|
|
||||||
|
m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
|
||||||
|
if (m_DomainScripts[instance.AppDomain].Count == 0)
|
||||||
|
{
|
||||||
|
m_DomainScripts.Remove(instance.AppDomain);
|
||||||
|
UnloadAppDomain(instance.AppDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
instance = null;
|
||||||
|
|
||||||
|
ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
|
||||||
|
if (handlerObjectRemoved != null)
|
||||||
|
handlerObjectRemoved(part.UUID);
|
||||||
|
|
||||||
|
CleanAssemblies();
|
||||||
|
|
||||||
|
|
||||||
ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
|
ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
|
||||||
if (handlerScriptRemoved != null)
|
if (handlerScriptRemoved != null)
|
||||||
handlerScriptRemoved(itemID);
|
handlerScriptRemoved(itemID);
|
||||||
|
@ -1091,12 +1163,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
private IScriptInstance GetInstance(UUID itemID)
|
private IScriptInstance GetInstance(UUID itemID)
|
||||||
{
|
{
|
||||||
IScriptInstance instance;
|
IScriptInstance instance;
|
||||||
lock (m_Scripts)
|
lockScriptsForRead(true);
|
||||||
|
if (!m_Scripts.ContainsKey(itemID))
|
||||||
{
|
{
|
||||||
if (!m_Scripts.ContainsKey(itemID))
|
lockScriptsForRead(false);
|
||||||
return null;
|
return null;
|
||||||
instance = m_Scripts[itemID];
|
|
||||||
}
|
}
|
||||||
|
instance = m_Scripts[itemID];
|
||||||
|
lockScriptsForRead(false);
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1200,11 +1274,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
{
|
{
|
||||||
List<IScriptInstance> instances = new List<IScriptInstance>();
|
List<IScriptInstance> instances = new List<IScriptInstance>();
|
||||||
|
|
||||||
lock (m_Scripts)
|
lockScriptsForRead(true);
|
||||||
{
|
foreach (IScriptInstance instance in m_Scripts.Values)
|
||||||
foreach (IScriptInstance instance in m_Scripts.Values)
|
|
||||||
instances.Add(instance);
|
instances.Add(instance);
|
||||||
}
|
lockScriptsForRead(false);
|
||||||
|
|
||||||
foreach (IScriptInstance i in instances)
|
foreach (IScriptInstance i in instances)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue