Implement suspended updates - When an operation is occurring on lots of prims in a single group, don't schedule any updates until the operation has completed. This makes things like llSetAlpha(LINK_SET,0.0,ALL_SIDES); a *lot* faster, more efficient and less buggy, and also makes unlinking a lot better. Linking is still treacherous.. this needs to be analysed.

This commit is contained in:
Tom Grimshaw
2010-05-29 02:10:34 -07:00
parent 3a5d379db8
commit e3dac1292e
5 changed files with 168 additions and 39 deletions

View File

@@ -226,7 +226,8 @@ namespace OpenSim.Region.Framework
"[MODULES]: Could not load types for [{0}]. Exception {1}", pluginAssembly.FullName, e);
// justincc: Right now this is fatal to really get the user's attention
throw e;
// TomMeta: WTF? No, how about we /don't/ throw a fatal exception when there's no need to?
//throw e;
}
}

View File

@@ -1499,10 +1499,13 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="childPrims"></param>
protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
{
SceneObjectGroup parentGroup = root.ParentGroup;
if (parentGroup == null) return;
Monitor.Enter(m_updateLock);
try
{
SceneObjectGroup parentGroup = root.ParentGroup;
parentGroup.areUpdatesSuspended = true;
List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
if (parentGroup != null)
@@ -1541,12 +1544,12 @@ namespace OpenSim.Region.Framework.Scenes
// occur on link to invoke this elsewhere (such as object selection)
parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected);
parentGroup.TriggerScriptChangedEvent(Changed.LINK);
parentGroup.HasGroupChanged = true;
parentGroup.ScheduleGroupForFullUpdate();
}
finally
{
parentGroup.areUpdatesSuspended = false;
parentGroup.HasGroupChanged = true;
parentGroup.ScheduleGroupForFullUpdate();
Monitor.Exit(m_updateLock);
}
}
@@ -1583,11 +1586,22 @@ namespace OpenSim.Region.Framework.Scenes
}
}
foreach (SceneObjectPart child in childParts)
if (childParts.Count > 0)
{
// Unlink all child parts from their groups
//
child.ParentGroup.DelinkFromGroup(child, true);
try
{
childParts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart child in childParts)
{
// Unlink all child parts from their groups
//
child.ParentGroup.DelinkFromGroup(child, true);
}
}
finally
{
childParts[0].ParentGroup.areUpdatesSuspended = false;
}
}
foreach (SceneObjectPart root in rootParts)
@@ -1611,10 +1625,21 @@ namespace OpenSim.Region.Framework.Scenes
if (numChildren > 1)
sendEventsToRemainder = false;
foreach (SceneObjectPart p in newSet)
if (newSet.Count > 0)
{
if (p != group.RootPart)
group.DelinkFromGroup(p, sendEventsToRemainder);
try
{
newSet[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart p in newSet)
{
if (p != group.RootPart)
group.DelinkFromGroup(p, sendEventsToRemainder);
}
}
finally
{
newSet[0].ParentGroup.areUpdatesSuspended = false;
}
}
// If there is more than one prim remaining, we

View File

@@ -109,9 +109,26 @@ namespace OpenSim.Region.Framework.Scenes
private long m_maxPersistTime = 0;
private long m_minPersistTime = 0;
private Random m_rand;
private bool m_suspendUpdates;
private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
public bool areUpdatesSuspended
{
get
{
return m_suspendUpdates;
}
set
{
m_suspendUpdates = value;
if (!value)
{
QueueForUpdateCheck();
}
}
}
public void lockPartsForRead(bool locked)
{
if (locked)

View File

@@ -2724,7 +2724,10 @@ namespace OpenSim.Region.Framework.Scenes
if (m_parentGroup != null)
{
m_parentGroup.QueueForUpdateCheck();
if (!m_parentGroup.areUpdatesSuspended)
{
m_parentGroup.QueueForUpdateCheck();
}
}
int timeNow = Util.UnixTimeSinceEpoch();
@@ -4450,8 +4453,9 @@ namespace OpenSim.Region.Framework.Scenes
{
m_shape.TextureEntry = textureEntry;
TriggerScriptChangedEvent(Changed.TEXTURE);
m_updateFlag = 1;
ParentGroup.HasGroupChanged = true;
//This is madness..
//ParentGroup.ScheduleGroupForFullUpdate();
//This is sparta