aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2010-09-07 00:34:06 +0100
committerMelanie2010-09-07 01:43:20 +0100
commit3d033520fafa1431c52086d741d1f3c7409bc6eb (patch)
treef16956aa3d2cac3ae325ffda621f2bd79b40310e /OpenSim/Region/Framework
parentAdd test that checks correct persistence when an unlink is quickly followed b... (diff)
downloadopensim-SC-3d033520fafa1431c52086d741d1f3c7409bc6eb.zip
opensim-SC-3d033520fafa1431c52086d741d1f3c7409bc6eb.tar.gz
opensim-SC-3d033520fafa1431c52086d741d1f3c7409bc6eb.tar.bz2
opensim-SC-3d033520fafa1431c52086d741d1f3c7409bc6eb.tar.xz
Fix deletion persistence when freshly delinked prims are removed
Previously, Scene.Inventory.DeRezObjects() forced the persistence of prims before deletion. This is necessary so that freshly delinked prims can be deleted (otherwise they remain as parts of their old group and reappear on server restart). However, DeRezObjects() deleted to user inventory, which is not required by llDie() or direct region module unlink and deletion. Therefore, forced persistence has been pushed down into Scene.UnlinkSceneObject() to be more general, this is still on the DeRezObjects() path. Uncommented TestDelinkPersistence() since this now passes. Tests required considerable elaboration of MockRegionDataPlugin to reflect underlying storing of parts.
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs21
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityBase.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs25
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs42
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs4
6 files changed, 58 insertions, 42 deletions
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
index 241cac0..916148b 100644
--- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
+++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
@@ -111,11 +111,11 @@ namespace OpenSim.Region.Framework.Scenes
111 111
112 private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) 112 private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e)
113 { 113 {
114 m_log.Debug("[SCENE]: Starting send to inventory loop"); 114 m_log.Debug("[ASYNC DELETER]: Starting send to inventory loop");
115 115
116 while (InventoryDeQueueAndDelete()) 116 while (InventoryDeQueueAndDelete())
117 { 117 {
118 //m_log.Debug("[SCENE]: Sent item successfully to inventory, continuing..."); 118 //m_log.Debug("[ASYNC DELETER]: Sent item successfully to inventory, continuing...");
119 } 119 }
120 } 120 }
121 121
@@ -137,7 +137,7 @@ namespace OpenSim.Region.Framework.Scenes
137 x = m_inventoryDeletes.Dequeue(); 137 x = m_inventoryDeletes.Dequeue();
138 138
139 m_log.DebugFormat( 139 m_log.DebugFormat(
140 "[SCENE]: Sending object to user's inventory, {0} item(s) remaining.", left); 140 "[ASYNC DELETER]: Sending object to user's inventory, {0} item(s) remaining.", left);
141 141
142 try 142 try
143 { 143 {
@@ -152,7 +152,8 @@ namespace OpenSim.Region.Framework.Scenes
152 } 152 }
153 catch (Exception e) 153 catch (Exception e)
154 { 154 {
155 m_log.DebugFormat("Exception background sending object: " + e); 155 m_log.ErrorFormat(
156 "[ASYNC DELETER]: Exception background sending object: {0}{1}", e.Message, e.StackTrace);
156 } 157 }
157 158
158 return true; 159 return true;
@@ -164,12 +165,16 @@ namespace OpenSim.Region.Framework.Scenes
164 // We can't put the object group details in here since the root part may have disappeared (which is where these sit). 165 // We can't put the object group details in here since the root part may have disappeared (which is where these sit).
165 // FIXME: This needs to be fixed. 166 // FIXME: This needs to be fixed.
166 m_log.ErrorFormat( 167 m_log.ErrorFormat(
167 "[SCENE]: Queued sending of scene object to agent {0} {1} failed: {2}", 168 "[ASYNC DELETER]: Queued sending of scene object to agent {0} {1} failed: {2} {3}",
168 (x != null ? x.remoteClient.Name : "unavailable"), (x != null ? x.remoteClient.AgentId.ToString() : "unavailable"), e.ToString()); 169 (x != null ? x.remoteClient.Name : "unavailable"),
170 (x != null ? x.remoteClient.AgentId.ToString() : "unavailable"),
171 e.Message,
172 e.StackTrace);
169 } 173 }
170 174
171 m_log.Debug("[SCENE]: No objects left in inventory send queue."); 175 m_log.Debug("[ASYNC DELETER]: No objects left in inventory send queue.");
176
172 return false; 177 return false;
173 } 178 }
174 } 179 }
175} 180} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs
index e183f9d..6fd38e5 100644
--- a/OpenSim/Region/Framework/Scenes/EntityBase.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs
@@ -69,6 +69,7 @@ namespace OpenSim.Region.Framework.Scenes
69 public bool IsDeleted 69 public bool IsDeleted
70 { 70 {
71 get { return m_isDeleted; } 71 get { return m_isDeleted; }
72 set { m_isDeleted = value; }
72 } 73 }
73 protected bool m_isDeleted; 74 protected bool m_isDeleted;
74 75
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 4e871d9..c49386a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -1720,7 +1720,7 @@ namespace OpenSim.Region.Framework.Scenes
1720 public virtual void DeRezObject(IClientAPI remoteClient, uint localID, 1720 public virtual void DeRezObject(IClientAPI remoteClient, uint localID,
1721 UUID groupID, DeRezAction action, UUID destinationID) 1721 UUID groupID, DeRezAction action, UUID destinationID)
1722 { 1722 {
1723 DeRezObjects(remoteClient, new List<uint>() { localID} , groupID, action, destinationID); 1723 DeRezObjects(remoteClient, new List<uint>() { localID }, groupID, action, destinationID);
1724 } 1724 }
1725 1725
1726 public virtual void DeRezObjects(IClientAPI remoteClient, List<uint> localIDs, 1726 public virtual void DeRezObjects(IClientAPI remoteClient, List<uint> localIDs,
@@ -1757,11 +1757,6 @@ namespace OpenSim.Region.Framework.Scenes
1757 deleteIDs.Add(localID); 1757 deleteIDs.Add(localID);
1758 deleteGroups.Add(grp); 1758 deleteGroups.Add(grp);
1759 1759
1760 // Force a database backup/update on this SceneObjectGroup
1761 // So that we know the database is upto date,
1762 // for when deleting the object from it
1763 ForceSceneObjectBackup(grp);
1764
1765 if (remoteClient == null) 1760 if (remoteClient == null)
1766 { 1761 {
1767 // Autoreturn has a null client. Nothing else does. So 1762 // Autoreturn has a null client. Nothing else does. So
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 183310d..82e7d76 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2092,7 +2092,7 @@ namespace OpenSim.Region.Framework.Scenes
2092// rootPart.PhysActor = null; 2092// rootPart.PhysActor = null;
2093// } 2093// }
2094 2094
2095 if (UnlinkSceneObject(group.UUID, false)) 2095 if (UnlinkSceneObject(group, false))
2096 { 2096 {
2097 EventManager.TriggerObjectBeingRemovedFromScene(group); 2097 EventManager.TriggerObjectBeingRemovedFromScene(group);
2098 EventManager.TriggerParcelPrimCountTainted(); 2098 EventManager.TriggerParcelPrimCountTainted();
@@ -2107,18 +2107,25 @@ namespace OpenSim.Region.Framework.Scenes
2107 /// Unlink the given object from the scene. Unlike delete, this just removes the record of the object - the 2107 /// Unlink the given object from the scene. Unlike delete, this just removes the record of the object - the
2108 /// object itself is not destroyed. 2108 /// object itself is not destroyed.
2109 /// </summary> 2109 /// </summary>
2110 /// <param name="uuid">Id of object.</param> 2110 /// <param name="so">The scene object.</param>
2111 /// <param name="softDelete">If true, only deletes from scene, but keeps the object in the database.</param>
2111 /// <returns>true if the object was in the scene, false if it was not</returns> 2112 /// <returns>true if the object was in the scene, false if it was not</returns>
2112 /// <param name="softDelete">If true, only deletes from scene, but keeps object in database.</param> 2113 public bool UnlinkSceneObject(SceneObjectGroup so, bool softDelete)
2113 public bool UnlinkSceneObject(UUID uuid, bool softDelete)
2114 { 2114 {
2115 if (m_sceneGraph.DeleteSceneObject(uuid, softDelete)) 2115 if (m_sceneGraph.DeleteSceneObject(so.UUID, softDelete))
2116 { 2116 {
2117 if (!softDelete) 2117 if (!softDelete)
2118 { 2118 {
2119 m_storageManager.DataStore.RemoveObject(uuid, 2119 // Force a database update so that the scene object group ID is accurate. It's possible that the
2120 m_regInfo.RegionID); 2120 // group has recently been delinked from another group but that this change has not been persisted
2121 // to the DB.
2122 ForceSceneObjectBackup(so);
2123 so.DetachFromBackup();
2124 m_storageManager.DataStore.RemoveObject(so.UUID, m_regInfo.RegionID);
2121 } 2125 }
2126
2127 // We need to keep track of this state in case this group is still queued for further backup.
2128 so.IsDeleted = true;
2122 2129
2123 return true; 2130 return true;
2124 } 2131 }
@@ -2149,7 +2156,7 @@ namespace OpenSim.Region.Framework.Scenes
2149 } 2156 }
2150 catch (Exception) 2157 catch (Exception)
2151 { 2158 {
2152 m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border."); 2159 m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border.");
2153 } 2160 }
2154 return; 2161 return;
2155 } 2162 }
@@ -2166,7 +2173,7 @@ namespace OpenSim.Region.Framework.Scenes
2166 } 2173 }
2167 catch (Exception) 2174 catch (Exception)
2168 { 2175 {
2169 m_log.Warn("[DATABASE]: exception when trying to return the prim that crossed the border."); 2176 m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border.");
2170 } 2177 }
2171 return; 2178 return;
2172 } 2179 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index b8b3db5..09e3e0e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1226,16 +1226,16 @@ namespace OpenSim.Region.Framework.Scenes
1226 } 1226 }
1227 1227
1228 /// <summary> 1228 /// <summary>
1229 /// Delete this group from its scene and tell all the scene presences about that deletion. 1229 /// Delete this group from its scene.
1230 /// </summary> 1230 /// </summary>
1231 /// <param name="silent">Broadcast deletions to all clients.</param> 1231 ///
1232 /// This only handles the in-world consequences of deletion (e.g. any avatars sitting on it are forcibly stood
1233 /// up and all avatars receive notification of its removal. Removal of the scene object from database backup
1234 /// must be handled by the caller.
1235 ///
1236 /// <param name="silent">If true then deletion is not broadcast to clients</param>
1232 public void DeleteGroup(bool silent) 1237 public void DeleteGroup(bool silent)
1233 { 1238 {
1234 // We need to keep track of this state in case this group is still queued for backup.
1235 m_isDeleted = true;
1236
1237 DetachFromBackup();
1238
1239 lock (m_parts) 1239 lock (m_parts)
1240 { 1240 {
1241 foreach (SceneObjectPart part in m_parts.Values) 1241 foreach (SceneObjectPart part in m_parts.Values)
@@ -1381,10 +1381,18 @@ namespace OpenSim.Region.Framework.Scenes
1381 public virtual void ProcessBackup(IRegionDataStore datastore, bool forcedBackup) 1381 public virtual void ProcessBackup(IRegionDataStore datastore, bool forcedBackup)
1382 { 1382 {
1383 if (!m_isBackedUp) 1383 if (!m_isBackedUp)
1384 {
1385// m_log.DebugFormat(
1386// "[WATER WARS]: Ignoring backup of {0} {1} since object is not marked to be backed up", Name, UUID);
1384 return; 1387 return;
1388 }
1385 1389
1386 if (IsDeleted || UUID == UUID.Zero) 1390 if (IsDeleted || UUID == UUID.Zero)
1391 {
1392// m_log.DebugFormat(
1393// "[WATER WARS]: Ignoring backup of {0} {1} since object is marked as already deleted", Name, UUID);
1387 return; 1394 return;
1395 }
1388 1396
1389 // Since this is the top of the section of call stack for backing up a particular scene object, don't let 1397 // Since this is the top of the section of call stack for backing up a particular scene object, don't let
1390 // any exception propogate upwards. 1398 // any exception propogate upwards.
@@ -1420,7 +1428,7 @@ namespace OpenSim.Region.Framework.Scenes
1420 if (HasGroupChanged) 1428 if (HasGroupChanged)
1421 { 1429 {
1422 // don't backup while it's selected or you're asking for changes mid stream. 1430 // don't backup while it's selected or you're asking for changes mid stream.
1423 if ((isTimeToPersist()) || (forcedBackup)) 1431 if (isTimeToPersist() || forcedBackup)
1424 { 1432 {
1425 m_log.DebugFormat( 1433 m_log.DebugFormat(
1426 "[SCENE]: Storing {0}, {1} in {2}", 1434 "[SCENE]: Storing {0}, {1} in {2}",
@@ -1443,19 +1451,19 @@ namespace OpenSim.Region.Framework.Scenes
1443 1451
1444 backup_group = null; 1452 backup_group = null;
1445 } 1453 }
1446 // else 1454// else
1447 // { 1455// {
1448 // m_log.DebugFormat( 1456// m_log.DebugFormat(
1449 // "[SCENE]: Did not update persistence of object {0} {1}, selected = {2}", 1457// "[SCENE]: Did not update persistence of object {0} {1}, selected = {2}",
1450 // Name, UUID, IsSelected); 1458// Name, UUID, IsSelected);
1451 // } 1459// }
1452 } 1460 }
1453 } 1461 }
1454 catch (Exception e) 1462 catch (Exception e)
1455 { 1463 {
1456 m_log.ErrorFormat( 1464 m_log.ErrorFormat(
1457 "[SCENE]: Storing of {0}, {1} in {2} failed with exception {3}\n\t{4}", 1465 "[SCENE]: Storing of {0}, {1} in {2} failed with exception {3}{4}",
1458 Name, UUID, m_scene.RegionInfo.RegionName, e, e.StackTrace); 1466 Name, UUID, m_scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1459 } 1467 }
1460 } 1468 }
1461 1469
@@ -2245,7 +2253,7 @@ namespace OpenSim.Region.Framework.Scenes
2245 } 2253 }
2246 } 2254 }
2247 2255
2248 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2256 m_scene.UnlinkSceneObject(objectGroup, true);
2249 objectGroup.m_isDeleted = true; 2257 objectGroup.m_isDeleted = true;
2250 2258
2251 lock (objectGroup.m_parts) 2259 lock (objectGroup.m_parts)
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
index 93409fa..62761fb 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
@@ -303,11 +303,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
303 /// <summary> 303 /// <summary>
304 /// Test that a delink of a previously linked object is correctly persisted to the database 304 /// Test that a delink of a previously linked object is correctly persisted to the database
305 /// </summary> 305 /// </summary>
306 //[Test] 306 [Test]
307 public void TestDelinkPersistence() 307 public void TestDelinkPersistence()
308 { 308 {
309 TestHelper.InMethod(); 309 TestHelper.InMethod();
310 //log4net.Config.XmlConfigurator.Configure(); 310 log4net.Config.XmlConfigurator.Configure();
311 311
312 TestScene scene = SceneSetupHelpers.SetupScene(); 312 TestScene scene = SceneSetupHelpers.SetupScene();
313 313