From 5af108a029e5382f6a2f6d4d10b3d4de3a8f5245 Mon Sep 17 00:00:00 2001
From: Teravus Ovares
Date: Wed, 21 May 2008 21:22:56 +0000
Subject: * This update causes the backup process to run in a separate thread.
* Concurrency issues are resolved because each object makes a memory-only
copy of itself and backs up the copy. * Because of the way this is done, the
latest at the time of the backup gets backed up (no functionality change) *
You can move *thousands of objects at a time* and the sim doesn't freeze and
wait for the backup to complete. * This can be enhanced more by dedicating
the thread as opposed to starting it when the backup process starts.
---
OpenSim/Region/Environment/Scenes/EventManager.cs | 10 +++-
OpenSim/Region/Environment/Scenes/InnerScene.cs | 2 +-
OpenSim/Region/Environment/Scenes/Scene.cs | 16 +++++-
.../Region/Environment/Scenes/SceneObjectGroup.cs | 65 +++++++++++++++-------
.../Scenes/SceneObjectPart.Inventory.cs | 7 ++-
.../Region/Environment/Scenes/SceneObjectPart.cs | 22 +++++---
6 files changed, 85 insertions(+), 37 deletions(-)
diff --git a/OpenSim/Region/Environment/Scenes/EventManager.cs b/OpenSim/Region/Environment/Scenes/EventManager.cs
index 7ff9213..c6daa28 100644
--- a/OpenSim/Region/Environment/Scenes/EventManager.cs
+++ b/OpenSim/Region/Environment/Scenes/EventManager.cs
@@ -355,10 +355,16 @@ namespace OpenSim.Region.Environment.Scenes
public void TriggerOnBackup(IRegionDataStore dstore)
{
handlerBackup = OnBackup;
- if (handlerBackup != null)
+ Delegate[] items = OnBackup.GetInvocationList();
+ foreach (OnBackupDelegate del in items)
{
- handlerBackup(dstore);
+ if (del != null)
+ del(dstore);
}
+ //if (handlerBackup != null)
+ //{
+ // handlerBackup(dstore);
+ //}
}
public void TriggerParcelPrimCountUpdate()
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs
index 62055d8..695cb88 100644
--- a/OpenSim/Region/Environment/Scenes/InnerScene.cs
+++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs
@@ -1399,7 +1399,7 @@ namespace OpenSim.Region.Environment.Scenes
{
if (m_parentScene.ExternalChecks.ExternalChecksCanDuplicateObject(originPrim.Children.Count, originPrim.UUID, AgentID, originPrim.AbsolutePosition))
{
- SceneObjectGroup copy = originPrim.Copy(AgentID, GroupID);
+ SceneObjectGroup copy = originPrim.Copy(AgentID, GroupID, true);
copy.AbsolutePosition = copy.AbsolutePosition + offset;
copy.ResetIDs();
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 56d114c..280e09a 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -58,6 +58,7 @@ namespace OpenSim.Region.Environment.Scenes
public SynchronizeSceneHandler SynchronizeScene = null;
public int splitID = 0;
+
#region Fields
protected Timer m_heartbeatTimer = new Timer();
@@ -83,6 +84,7 @@ namespace OpenSim.Region.Environment.Scenes
private int m_RestartTimerCounter;
private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
private int m_incrementsof15seconds = 0;
+ private bool m_backingup = false;
public string m_simulatorVersion = "OpenSimulator 0.5";
@@ -842,7 +844,14 @@ namespace OpenSim.Region.Environment.Scenes
private void UpdateStorageBackup()
{
- Backup();
+ if (!m_backingup)
+ {
+ m_backingup = true;
+ Thread backupthread = new Thread(Backup);
+ backupthread.Name = "BackupWriter";
+ backupthread.IsBackground = true;
+ backupthread.Start();
+ }
}
private void UpdateEvents()
@@ -863,10 +872,11 @@ namespace OpenSim.Region.Environment.Scenes
///
///
///
- public bool Backup()
+ public void Backup()
{
EventManager.TriggerOnBackup(m_storageManager.DataStore);
- return true;
+ m_backingup = false;
+ //return true;
}
#endregion
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
index 44e4c81..4b82bf9 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
@@ -1085,13 +1085,24 @@ namespace OpenSim.Region.Environment.Scenes
///
public void ProcessBackup(IRegionDataStore datastore)
{
- if (HasGroupChanged)
+ // don't backup while it's selected or you're asking for changes mid stream.
+ if (HasGroupChanged && !IsSelected)
{
- datastore.StoreObject(this, m_scene.RegionInfo.RegionID);
+ m_log.Info("STORING");
+ SceneObjectGroup backup_group = Copy(OwnerID, GroupID, false);
+
+ datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
HasGroupChanged = false;
+
+ backup_group.ForEachPart(delegate(SceneObjectPart part) { part.ProcessInventoryBackup(datastore); });
+
+ backup_group = null;
}
+
+ // Why is storing the inventory outside of HasGroupChanged?
- ForEachPart(delegate(SceneObjectPart part) { part.ProcessInventoryBackup(datastore); });
+
+ //ForEachPart(delegate(SceneObjectPart part) { part.ProcessInventoryBackup(datastore); });
}
#endregion
@@ -1165,7 +1176,7 @@ namespace OpenSim.Region.Environment.Scenes
/// Duplicates this object, including operations such as physics set up and attaching to the backup event.
///
///
- public SceneObjectGroup Copy(LLUUID cAgentID, LLUUID cGroupID)
+ public SceneObjectGroup Copy(LLUUID cAgentID, LLUUID cGroupID, bool userExposed)
{
SceneObjectGroup dupe = (SceneObjectGroup) MemberwiseClone();
dupe.m_parts = new Dictionary();
@@ -1176,11 +1187,13 @@ namespace OpenSim.Region.Environment.Scenes
dupe.m_scene = m_scene;
dupe.m_regionHandle = m_regionHandle;
- dupe.CopyRootPart(m_rootPart, OwnerID, GroupID);
- dupe.m_rootPart.TrimPermissions();
+ dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed);
+
+ if (userExposed)
+ dupe.m_rootPart.TrimPermissions();
/// may need to create a new Physics actor.
- if (dupe.RootPart.PhysActor != null)
+ if (dupe.RootPart.PhysActor != null && userExposed)
{
PrimitiveBaseShape pbs = dupe.RootPart.Shape;
@@ -1202,26 +1215,36 @@ namespace OpenSim.Region.Environment.Scenes
// switch the owner to the person who did the copying
// Second Life copies an object and duplicates the first one in it's place
// So, we have to make a copy of this one, set it in it's place then set the owner on this one
+ if (userExposed)
+ {
+ SetRootPartOwner(m_rootPart, cAgentID, cGroupID);
+ m_rootPart.ScheduleFullUpdate();
+ }
- SetRootPartOwner(m_rootPart, cAgentID, cGroupID);
-
-
- m_rootPart.ScheduleFullUpdate();
+
List partList = new List(m_parts.Values);
foreach (SceneObjectPart part in partList)
{
if (part.UUID != m_rootPart.UUID)
{
- dupe.CopyPart(part, OwnerID, GroupID);
- SetPartOwner(part, cAgentID, cGroupID);
- part.ScheduleFullUpdate();
+ dupe.CopyPart(part, OwnerID, GroupID, userExposed);
+
+ if (userExposed)
+ {
+ SetPartOwner(part, cAgentID, cGroupID);
+ part.ScheduleFullUpdate();
+ }
}
}
- dupe.UpdateParentIDs();
- dupe.AttachToBackup();
- ScheduleGroupForFullUpdate();
+ if (userExposed)
+ {
+ dupe.UpdateParentIDs();
+
+ dupe.AttachToBackup();
+ ScheduleGroupForFullUpdate();
+ }
return dupe;
}
@@ -1232,9 +1255,9 @@ namespace OpenSim.Region.Environment.Scenes
///
///
///
- public void CopyRootPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID)
+ public void CopyRootPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID, bool userExposed)
{
- SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
+ SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count, userExposed);
newPart.SetParent(this);
lock (m_parts)
@@ -1364,9 +1387,9 @@ namespace OpenSim.Region.Environment.Scenes
///
///
///
- public void CopyPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID)
+ public void CopyPart(SceneObjectPart part, LLUUID cAgentID, LLUUID cGroupID, bool userExposed)
{
- SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
+ SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count, userExposed);
newPart.SetParent(this);
lock (m_parts)
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
index d63260d..51521ff 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
@@ -99,7 +99,7 @@ namespace OpenSim.Region.Environment.Scenes
}
HasInventoryChanged = true;
-
+ ParentGroup.HasGroupChanged = true;
IList items = new List(TaskInventory.Values);
TaskInventory.Clear();
@@ -121,7 +121,7 @@ namespace OpenSim.Region.Environment.Scenes
}
HasInventoryChanged = true;
-
+ ParentGroup.HasGroupChanged = true;
IList items = new List(TaskInventory.Values);
foreach (TaskInventoryItem item in items)
{
@@ -304,6 +304,7 @@ namespace OpenSim.Region.Environment.Scenes
m_inventorySerial++;
//m_inventorySerial += 2;
HasInventoryChanged = true;
+ ParentGroup.HasGroupChanged = true;
}
///
@@ -373,6 +374,7 @@ namespace OpenSim.Region.Environment.Scenes
TriggerScriptChangedEvent(Changed.INVENTORY);
HasInventoryChanged = true;
+ ParentGroup.HasGroupChanged = true;
return true;
}
@@ -411,6 +413,7 @@ namespace OpenSim.Region.Environment.Scenes
TriggerScriptChangedEvent(Changed.INVENTORY);
HasInventoryChanged = true;
+ ParentGroup.HasGroupChanged = true;
int scriptcount = 0;
lock (m_taskInventory)
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
index f5d3618..d95143e 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
@@ -1523,12 +1523,14 @@ namespace OpenSim.Region.Environment.Scenes
/// Duplicates this part.
///
///
- public SceneObjectPart Copy(uint localID, LLUUID AgentID, LLUUID GroupID, int linkNum)
+ public SceneObjectPart Copy(uint localID, LLUUID AgentID, LLUUID GroupID, int linkNum, bool userExposed)
{
SceneObjectPart dupe = (SceneObjectPart) MemberwiseClone();
dupe.m_shape = m_shape.Copy();
dupe.m_regionHandle = m_regionHandle;
- dupe.UUID = LLUUID.Random();
+ if (userExposed)
+ dupe.UUID = LLUUID.Random();
+
dupe.LocalId = localID;
dupe.OwnerID = AgentID;
dupe.GroupID = GroupID;
@@ -1548,7 +1550,8 @@ namespace OpenSim.Region.Environment.Scenes
dupe.TaskInventory = (TaskInventoryDictionary)dupe.TaskInventory.Clone();
- dupe.ResetIDs(linkNum);
+ if (userExposed)
+ dupe.ResetIDs(linkNum);
// This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
dupe.LastOwnerID = ObjectOwner;
@@ -1556,13 +1559,16 @@ namespace OpenSim.Region.Environment.Scenes
byte[] extraP = new byte[Shape.ExtraParams.Length];
Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
dupe.Shape.ExtraParams = extraP;
- if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != LLUUID.Zero)
+
+ if (userExposed)
{
- m_parentGroup.Scene.AssetCache.GetAsset(dupe.m_shape.SculptTexture, dupe.SculptTextureCallback, true);
+ if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != LLUUID.Zero)
+ {
+ m_parentGroup.Scene.AssetCache.GetAsset(dupe.m_shape.SculptTexture, dupe.SculptTextureCallback, true);
+ }
+ bool UsePhysics = ((dupe.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0);
+ dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
}
- bool UsePhysics = ((dupe.ObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0);
- dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
-
return dupe;
}
--
cgit v1.1