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.

avinationmerge
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); "[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 // 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> /// <param name="childPrims"></param>
protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
{ {
SceneObjectGroup parentGroup = root.ParentGroup;
if (parentGroup == null) return;
Monitor.Enter(m_updateLock); Monitor.Enter(m_updateLock);
try try
{ {
SceneObjectGroup parentGroup = root.ParentGroup; parentGroup.areUpdatesSuspended = true;
List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
if (parentGroup != null) if (parentGroup != null)
@ -1541,12 +1544,12 @@ namespace OpenSim.Region.Framework.Scenes
// occur on link to invoke this elsewhere (such as object selection) // occur on link to invoke this elsewhere (such as object selection)
parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected);
parentGroup.TriggerScriptChangedEvent(Changed.LINK); parentGroup.TriggerScriptChangedEvent(Changed.LINK);
parentGroup.HasGroupChanged = true;
parentGroup.ScheduleGroupForFullUpdate();
} }
finally finally
{ {
parentGroup.areUpdatesSuspended = false;
parentGroup.HasGroupChanged = true;
parentGroup.ScheduleGroupForFullUpdate();
Monitor.Exit(m_updateLock); 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 try
// {
child.ParentGroup.DelinkFromGroup(child, true); 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) foreach (SceneObjectPart root in rootParts)
@ -1611,10 +1625,21 @@ namespace OpenSim.Region.Framework.Scenes
if (numChildren > 1) if (numChildren > 1)
sendEventsToRemainder = false; sendEventsToRemainder = false;
foreach (SceneObjectPart p in newSet) if (newSet.Count > 0)
{ {
if (p != group.RootPart) try
group.DelinkFromGroup(p, sendEventsToRemainder); {
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 // 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_maxPersistTime = 0;
private long m_minPersistTime = 0; private long m_minPersistTime = 0;
private Random m_rand; private Random m_rand;
private bool m_suspendUpdates;
private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim(); 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) public void lockPartsForRead(bool locked)
{ {
if (locked) if (locked)

View File

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

View File

@ -1649,9 +1649,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
List<SceneObjectPart> parts = GetLinkParts(linknumber); List<SceneObjectPart> parts = GetLinkParts(linknumber);
if (parts.Count > 0)
foreach (SceneObjectPart part in parts) {
SetAlpha(part, alpha, face); try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts)
SetAlpha(part, alpha, face);
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
}
} }
protected void SetAlpha(SceneObjectPart part, double alpha, int face) protected void SetAlpha(SceneObjectPart part, double alpha, int face)
@ -1816,10 +1826,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
List<SceneObjectPart> parts = GetLinkParts(linknumber); List<SceneObjectPart> parts = GetLinkParts(linknumber);
if (parts.Count > 0)
foreach (SceneObjectPart part in parts) {
SetTexture(part, texture, face); try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts)
SetTexture(part, texture, face);
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
}
ScriptSleep(200); ScriptSleep(200);
} }
@ -3661,9 +3680,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llSetLinkColor(int linknumber, LSL_Vector color, int face) public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
{ {
List<SceneObjectPart> parts = GetLinkParts(linknumber); List<SceneObjectPart> parts = GetLinkParts(linknumber);
if (parts.Count > 0)
foreach (SceneObjectPart part in parts) {
part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts)
part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
}
} }
public void llCreateLink(string target, int parent) public void llCreateLink(string target, int parent)
@ -3776,10 +3805,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// Restructuring Multiple Prims. // Restructuring Multiple Prims.
List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
parts.Remove(parentPrim.RootPart); parts.Remove(parentPrim.RootPart);
foreach (SceneObjectPart part in parts) if (parts.Count > 0)
{ {
parentPrim.DelinkFromGroup(part.LocalId, true); try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts)
{
parentPrim.DelinkFromGroup(part.LocalId, true);
}
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
} }
parentPrim.HasGroupChanged = true; parentPrim.HasGroupChanged = true;
parentPrim.ScheduleGroupForFullUpdate(); parentPrim.ScheduleGroupForFullUpdate();
parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@ -3788,11 +3829,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
SceneObjectPart newRoot = parts[0]; SceneObjectPart newRoot = parts[0];
parts.Remove(newRoot); parts.Remove(newRoot);
foreach (SceneObjectPart part in parts)
try
{ {
part.UpdateFlag = 0; parts[0].ParentGroup.areUpdatesSuspended = true;
newRoot.ParentGroup.LinkToGroup(part.ParentGroup); foreach (SceneObjectPart part in parts)
{
part.UpdateFlag = 0;
newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
}
} }
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
newRoot.ParentGroup.HasGroupChanged = true; newRoot.ParentGroup.HasGroupChanged = true;
newRoot.ParentGroup.ScheduleGroupForFullUpdate(); newRoot.ParentGroup.ScheduleGroupForFullUpdate();
} }
@ -3818,11 +3870,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
parts.Remove(parentPrim.RootPart); parts.Remove(parentPrim.RootPart);
if (parts.Count > 0)
foreach (SceneObjectPart part in parts)
{ {
parentPrim.DelinkFromGroup(part.LocalId, true); try
parentPrim.TriggerScriptChangedEvent(Changed.LINK); {
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts)
{
parentPrim.DelinkFromGroup(part.LocalId, true);
parentPrim.TriggerScriptChangedEvent(Changed.LINK);
}
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
} }
parentPrim.HasGroupChanged = true; parentPrim.HasGroupChanged = true;
parentPrim.ScheduleGroupForFullUpdate(); parentPrim.ScheduleGroupForFullUpdate();
@ -5664,10 +5726,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
List<SceneObjectPart> parts = GetLinkParts(linknumber); List<SceneObjectPart> parts = GetLinkParts(linknumber);
if (parts.Count > 0)
foreach (var part in parts)
{ {
SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (var part in parts)
{
SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
}
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
} }
} }
@ -7068,9 +7140,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
List<SceneObjectPart> parts = GetLinkParts(linknumber); List<SceneObjectPart> parts = GetLinkParts(linknumber);
if (parts.Count>0)
foreach (SceneObjectPart part in parts) {
SetPrimParams(part, rules); try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts)
SetPrimParams(part, rules);
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
}
} }
public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)