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,12 +1586,23 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
if (childParts.Count > 0)
{
try
{
childParts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart child in childParts) foreach (SceneObjectPart child in childParts)
{ {
// Unlink all child parts from their groups // Unlink all child parts from their groups
// //
child.ParentGroup.DelinkFromGroup(child, true); child.ParentGroup.DelinkFromGroup(child, true);
} }
}
finally
{
childParts[0].ParentGroup.areUpdatesSuspended = false;
}
}
foreach (SceneObjectPart root in rootParts) foreach (SceneObjectPart root in rootParts)
{ {
@ -1611,11 +1625,22 @@ namespace OpenSim.Region.Framework.Scenes
if (numChildren > 1) if (numChildren > 1)
sendEventsToRemainder = false; sendEventsToRemainder = false;
if (newSet.Count > 0)
{
try
{
newSet[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart p in newSet) foreach (SceneObjectPart p in newSet)
{ {
if (p != group.RootPart) if (p != group.RootPart)
group.DelinkFromGroup(p, sendEventsToRemainder); 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
// need to re-link // need to re-link

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

@ -2723,9 +2723,12 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); // m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId);
if (m_parentGroup != null) if (m_parentGroup != null)
{
if (!m_parentGroup.areUpdatesSuspended)
{ {
m_parentGroup.QueueForUpdateCheck(); 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,10 +1649,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)
{
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts) foreach (SceneObjectPart part in parts)
SetAlpha(part, alpha, face); 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)
{
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts) foreach (SceneObjectPart part in parts)
SetTexture(part, texture, face); SetTexture(part, texture, face);
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
}
ScriptSleep(200); ScriptSleep(200);
} }
@ -3661,10 +3680,20 @@ 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)
{
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts) foreach (SceneObjectPart part in parts)
part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 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);
if (parts.Count > 0)
{
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts) foreach (SceneObjectPart part in parts)
{ {
parentPrim.DelinkFromGroup(part.LocalId, true); 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);
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts) foreach (SceneObjectPart part in parts)
{ {
part.UpdateFlag = 0; part.UpdateFlag = 0;
newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 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,12 +3870,22 @@ 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)
{
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts) foreach (SceneObjectPart part in parts)
{ {
parentPrim.DelinkFromGroup(part.LocalId, true); parentPrim.DelinkFromGroup(part.LocalId, true);
parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.TriggerScriptChangedEvent(Changed.LINK);
} }
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
}
parentPrim.HasGroupChanged = true; parentPrim.HasGroupChanged = true;
parentPrim.ScheduleGroupForFullUpdate(); parentPrim.ScheduleGroupForFullUpdate();
} }
@ -5664,12 +5726,22 @@ 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)
{
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (var part in parts) foreach (var part in parts)
{ {
SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
} }
} }
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
}
}
private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate) private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate)
{ {
@ -7068,10 +7140,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)
{
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts) foreach (SceneObjectPart part in parts)
SetPrimParams(part, rules); 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)
{ {