From 9784e4e07db63a23897876dfbd27974878d5eca9 Mon Sep 17 00:00:00 2001
From: Oren Hurvitz
Date: Thu, 9 Aug 2012 14:51:05 +0300
Subject: Changed locks to prevent deadlocks (especially during multi-region
Load OAR)
---
.../World/Archiver/ArchiveReadRequest.cs | 42 ++++++++++++-------
.../CoreModules/World/Land/LandManagementModule.cs | 47 +++++++++++++---------
.../CoreModules/World/Land/PrimCountModule.cs | 11 +++--
3 files changed, 61 insertions(+), 39 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index c810242..32d245f 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -604,13 +604,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
///
private bool ResolveUserUuid(Scene scene, UUID uuid)
{
- if (!m_validUserUuids.ContainsKey(uuid))
+ lock (m_validUserUuids)
{
- UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, uuid);
- m_validUserUuids.Add(uuid, account != null);
- }
+ if (!m_validUserUuids.ContainsKey(uuid))
+ {
+ // Note: we call GetUserAccount() inside the lock because this UserID is likely
+ // to occur many times, and we only want to query the users service once.
+ UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, uuid);
+ m_validUserUuids.Add(uuid, account != null);
+ }
- return m_validUserUuids[uuid];
+ return m_validUserUuids[uuid];
+ }
}
///
@@ -623,19 +628,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver
if (uuid == UUID.Zero)
return true; // this means the object has no group
- if (!m_validGroupUuids.ContainsKey(uuid))
+ lock (m_validGroupUuids)
{
- bool exists;
-
- if (m_groupsModule == null)
- exists = false;
- else
- exists = (m_groupsModule.GetGroupRecord(uuid) != null);
+ if (!m_validGroupUuids.ContainsKey(uuid))
+ {
+ bool exists;
+ if (m_groupsModule == null)
+ {
+ exists = false;
+ }
+ else
+ {
+ // Note: we call GetGroupRecord() inside the lock because this GroupID is likely
+ // to occur many times, and we only want to query the groups service once.
+ exists = (m_groupsModule.GetGroupRecord(uuid) != null);
+ }
+ m_validGroupUuids.Add(uuid, exists);
+ }
- m_validGroupUuids.Add(uuid, exists);
+ return m_validGroupUuids[uuid];
}
-
- return m_validGroupUuids[uuid];
}
/// Load an asset
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index e85b7a2..4b1e6b9 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -287,14 +287,15 @@ namespace OpenSim.Region.CoreModules.World.Land
LandData newData = data.Copy();
newData.LocalID = local_id;
+ ILandObject land;
lock (m_landList)
{
- if (m_landList.ContainsKey(local_id))
- {
- m_landList[local_id].LandData = newData;
- m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]);
- }
+ if (m_landList.TryGetValue(local_id, out land))
+ land.LandData = newData;
}
+
+ if (land != null)
+ m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, land);
}
public bool AllowedForcefulBans
@@ -613,7 +614,7 @@ namespace OpenSim.Region.CoreModules.World.Land
// Only now can we add the prim counts to the land object - we rely on the global ID which is generated
// as a random UUID inside LandData initialization
if (m_primCountModule != null)
- new_land.PrimCounts = m_primCountModule.GetPrimCounts(new_land.LandData.GlobalID);
+ new_land.PrimCounts = m_primCountModule.GetPrimCounts(new_land.LandData.GlobalID);
lock (m_landList)
{
@@ -650,6 +651,7 @@ namespace OpenSim.Region.CoreModules.World.Land
/// Land.localID of the peice of land to remove.
public void removeLandObject(int local_id)
{
+ ILandObject land;
lock (m_landList)
{
for (int x = 0; x < 64; x++)
@@ -666,9 +668,11 @@ namespace OpenSim.Region.CoreModules.World.Land
}
}
- m_scene.EventManager.TriggerLandObjectRemoved(m_landList[local_id].LandData.GlobalID);
+ land = m_landList[local_id];
m_landList.Remove(local_id);
}
+
+ m_scene.EventManager.TriggerLandObjectRemoved(land.LandData.GlobalID);
}
///
@@ -676,21 +680,27 @@ namespace OpenSim.Region.CoreModules.World.Land
///
public void Clear(bool setupDefaultParcel)
{
+ List parcels;
lock (m_landList)
{
- foreach (ILandObject lo in m_landList.Values)
- {
- //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
- m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
- }
+ parcels = new List(m_landList.Values);
+ }
+
+ foreach (ILandObject lo in parcels)
+ {
+ //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
+ m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
+ }
+ lock (m_landList)
+ {
m_landList.Clear();
ResetSimLandObjects();
-
- if (setupDefaultParcel)
- CreateDefaultParcel();
}
+
+ if (setupDefaultParcel)
+ CreateDefaultParcel();
}
private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -1458,11 +1468,8 @@ namespace OpenSim.Region.CoreModules.World.Land
public void EventManagerOnNoLandDataFromStorage()
{
- lock (m_landList)
- {
- ResetSimLandObjects();
- CreateDefaultParcel();
- }
+ ResetSimLandObjects();
+ CreateDefaultParcel();
}
#endregion
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
index f9cc0cf..9b51cc8 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -490,11 +490,14 @@ namespace OpenSim.Region.CoreModules.World.Land
m_Scene.ForEachSOG(AddObject);
- List primcountKeys = new List(m_PrimCounts.Keys);
- foreach (UUID k in primcountKeys)
+ lock (m_PrimCounts)
{
- if (!m_OwnerMap.ContainsKey(k))
- m_PrimCounts.Remove(k);
+ List primcountKeys = new List(m_PrimCounts.Keys);
+ foreach (UUID k in primcountKeys)
+ {
+ if (!m_OwnerMap.ContainsKey(k))
+ m_PrimCounts.Remove(k);
+ }
}
m_Tainted = false;
--
cgit v1.1