From e3dac1292ef000daadda3e264354d8df0fc77c22 Mon Sep 17 00:00:00 2001
From: Tom Grimshaw
Date: Sat, 29 May 2010 02:10:34 -0700
Subject: 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.
---
OpenSim/Region/Framework/ModuleLoader.cs | 3 +-
OpenSim/Region/Framework/Scenes/SceneGraph.cs | 47 +++++++++++++++++-----
.../Region/Framework/Scenes/SceneObjectGroup.cs | 17 ++++++++
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 8 +++-
4 files changed, 61 insertions(+), 14 deletions(-)
(limited to 'OpenSim/Region/Framework')
diff --git a/OpenSim/Region/Framework/ModuleLoader.cs b/OpenSim/Region/Framework/ModuleLoader.cs
index 23be9c2..69ba2042 100644
--- a/OpenSim/Region/Framework/ModuleLoader.cs
+++ b/OpenSim/Region/Framework/ModuleLoader.cs
@@ -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;
}
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index d4658ec..445c2c8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -1499,10 +1499,13 @@ namespace OpenSim.Region.Framework.Scenes
///
protected internal void LinkObjects(SceneObjectPart root, List children)
{
+ SceneObjectGroup parentGroup = root.ParentGroup;
+ if (parentGroup == null) return;
Monitor.Enter(m_updateLock);
+
try
{
- SceneObjectGroup parentGroup = root.ParentGroup;
+ parentGroup.areUpdatesSuspended = true;
List childGroups = new List();
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
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index cee2be3..9ebb168 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -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)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index c84596b..6e73b65 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -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
--
cgit v1.1