From 7c124a5543534dde332d90e07dd72d9b52108836 Mon Sep 17 00:00:00 2001
From: Diva Canto
Date: Tue, 20 Jul 2010 05:59:18 -0700
Subject: Relaxed the ultra-conservative lock on m_items. Needs testing under
linux and stress.
---
.../Framework/Scenes/SceneObjectPartInventory.cs | 407 ++++++++++-----------
1 file changed, 188 insertions(+), 219 deletions(-)
(limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index b27dc59..517b387 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -118,20 +118,20 @@ namespace OpenSim.Region.Framework.Scenes
/// Link number for the part
public void ResetInventoryIDs()
{
- lock (Items)
+ lock (m_items)
{
- if (0 == Items.Count)
+ if (0 == m_items.Count)
return;
HasInventoryChanged = true;
m_part.ParentGroup.HasGroupChanged = true;
- IList items = new List(Items.Values);
- Items.Clear();
+ IList items = GetInventoryItems();
+ m_items.Clear();
foreach (TaskInventoryItem item in items)
{
item.ResetIDs(m_part.UUID);
- Items.Add(item.ItemID, item);
+ m_items.Add(item.ItemID, item);
}
}
}
@@ -148,17 +148,17 @@ namespace OpenSim.Region.Framework.Scenes
{
return;
}
+ }
- HasInventoryChanged = true;
- m_part.ParentGroup.HasGroupChanged = true;
- IList items = new List(Items.Values);
- foreach (TaskInventoryItem item in items)
+ HasInventoryChanged = true;
+ m_part.ParentGroup.HasGroupChanged = true;
+ List items = GetInventoryItems();
+ foreach (TaskInventoryItem item in items)
+ {
+ if (ownerId != item.OwnerID)
{
- if (ownerId != item.OwnerID)
- {
- item.LastOwnerID = item.OwnerID;
- item.OwnerID = ownerId;
- }
+ item.LastOwnerID = item.OwnerID;
+ item.OwnerID = ownerId;
}
}
}
@@ -175,17 +175,15 @@ namespace OpenSim.Region.Framework.Scenes
{
return;
}
+ }
- HasInventoryChanged = true;
- m_part.ParentGroup.HasGroupChanged = true;
- IList items = new List(Items.Values);
- foreach (TaskInventoryItem item in items)
- {
- if (groupID != item.GroupID)
- {
- item.GroupID = groupID;
- }
- }
+ HasInventoryChanged = true;
+ m_part.ParentGroup.HasGroupChanged = true;
+ List items = GetInventoryItems();
+ foreach (TaskInventoryItem item in items)
+ {
+ if (groupID != item.GroupID)
+ item.GroupID = groupID;
}
}
@@ -194,16 +192,9 @@ namespace OpenSim.Region.Framework.Scenes
///
public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
{
- lock (m_items)
- {
- foreach (TaskInventoryItem item in Items.Values)
- {
- if ((int)InventoryType.LSL == item.InvType)
- {
- CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
- }
- }
- }
+ List scripts = GetInventoryScripts();
+ foreach (TaskInventoryItem item in scripts)
+ CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
}
public ArrayList GetScriptErrors(UUID itemID)
@@ -236,16 +227,9 @@ namespace OpenSim.Region.Framework.Scenes
///
public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
{
- lock (Items)
- {
- foreach (TaskInventoryItem item in Items.Values)
- {
- if ((int)InventoryType.LSL == item.InvType)
- {
- RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
- }
- }
- }
+ List scripts = GetInventoryScripts();
+ foreach (TaskInventoryItem item in scripts)
+ RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
}
///
@@ -375,21 +359,15 @@ namespace OpenSim.Region.Framework.Scenes
///
public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
{
- lock (m_items)
- {
- if (m_items.ContainsKey(itemId))
- {
- CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
- }
- else
- {
- m_log.ErrorFormat(
- "[PRIM INVENTORY]: " +
- "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
- itemId, m_part.Name, m_part.UUID,
- m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
- }
- }
+ TaskInventoryItem item = GetInventoryItem(itemId);
+ if (item != null)
+ CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
+ else
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: " +
+ "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
+ itemId, m_part.Name, m_part.UUID,
+ m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
}
///
@@ -430,16 +408,18 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Check if the inventory holds an item with a given name.
- /// This method assumes that the task inventory is already locked.
///
///
///
private bool InventoryContainsName(string name)
{
- foreach (TaskInventoryItem item in Items.Values)
+ lock (m_items)
{
- if (item.Name == name)
- return true;
+ foreach (TaskInventoryItem item in m_items.Values)
+ {
+ if (item.Name == name)
+ return true;
+ }
}
return false;
}
@@ -482,12 +462,7 @@ namespace OpenSim.Region.Framework.Scenes
///
public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
{
- List il;
-
- lock (m_items)
- {
- il = new List(m_items.Values);
- }
+ List il = GetInventoryItems();
foreach (TaskInventoryItem i in il)
{
@@ -527,14 +502,12 @@ namespace OpenSim.Region.Framework.Scenes
item.GroupID = m_part.GroupID;
lock (m_items)
- {
m_items.Add(item.ItemID, item);
- if (allowedDrop)
- m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
- else
- m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
- }
+ if (allowedDrop)
+ m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
+ else
+ m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
m_inventorySerial++;
//m_inventorySerial += 2;
@@ -558,9 +531,8 @@ namespace OpenSim.Region.Framework.Scenes
m_items.Add(item.ItemID, item);
// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
}
+ m_inventorySerial++;
}
-
- m_inventorySerial++;
}
///
@@ -615,45 +587,44 @@ namespace OpenSim.Region.Framework.Scenes
public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents)
{
- lock(m_items)
+ TaskInventoryItem it = GetInventoryItem(item.ItemID);
+ if (it != null)
{
- if (m_items.ContainsKey(item.ItemID))
- {
- if (m_items.ContainsKey(item.ItemID))
- {
- item.ParentID = m_part.UUID;
- item.ParentPartID = m_part.UUID;
- item.Flags = m_items[item.ItemID].Flags;
-
- // If group permissions have been set on, check that the groupID is up to date in case it has
- // changed since permissions were last set.
- if (item.GroupPermissions != (uint)PermissionMask.None)
- item.GroupID = m_part.GroupID;
+ item.ParentID = m_part.UUID;
+ item.ParentPartID = m_part.UUID;
+ item.Flags = m_items[item.ItemID].Flags;
+
+ // If group permissions have been set on, check that the groupID is up to date in case it has
+ // changed since permissions were last set.
+ if (item.GroupPermissions != (uint)PermissionMask.None)
+ item.GroupID = m_part.GroupID;
- if (item.AssetID == UUID.Zero)
- {
- item.AssetID = m_items[item.ItemID].AssetID;
- }
- m_items[item.ItemID] = item;
- m_inventorySerial++;
- if (fireScriptEvents)
- m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
- HasInventoryChanged = true;
- m_part.ParentGroup.HasGroupChanged = true;
- return true;
- }
- else
- {
- m_log.ErrorFormat(
- "[PRIM INVENTORY]: " +
- "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
- item.ItemID, m_part.Name, m_part.UUID,
- m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
- }
+ if (item.AssetID == UUID.Zero)
+ item.AssetID = it.AssetID;
+ lock (m_items)
+ {
+ m_items[item.ItemID] = item;
+ m_inventorySerial++;
}
- return false;
+
+ if (fireScriptEvents)
+ m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
+
+ HasInventoryChanged = true;
+ m_part.ParentGroup.HasGroupChanged = true;
+ return true;
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: " +
+ "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
+ item.ItemID, m_part.Name, m_part.UUID,
+ m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
}
+ return false;
+
}
///
@@ -664,52 +635,37 @@ namespace OpenSim.Region.Framework.Scenes
/// in this prim's inventory.
public int RemoveInventoryItem(UUID itemID)
{
- lock (m_items)
+ TaskInventoryItem item = GetInventoryItem(itemID);
+ if (item != null)
{
- if (m_items.ContainsKey(itemID))
+ int type = m_items[itemID].InvType;
+ if (type == 10) // Script
{
- int type = m_items[itemID].InvType;
- if (type == 10) // Script
- {
- m_part.RemoveScriptEvents(itemID);
- m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
- }
- m_items.Remove(itemID);
- m_inventorySerial++;
- m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
-
- HasInventoryChanged = true;
- m_part.ParentGroup.HasGroupChanged = true;
+ m_part.RemoveScriptEvents(itemID);
+ m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
+ }
+ m_items.Remove(itemID);
+ m_inventorySerial++;
+ m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
- int scriptcount = 0;
- lock (m_items)
- {
- foreach (TaskInventoryItem item in m_items.Values)
- {
- if (item.Type == 10)
- {
- scriptcount++;
- }
- }
- }
+ HasInventoryChanged = true;
+ m_part.ParentGroup.HasGroupChanged = true;
- if (scriptcount <= 0)
- {
- m_part.RemFlag(PrimFlags.Scripted);
- }
+ if (!ContainsScripts())
+ m_part.RemFlag(PrimFlags.Scripted);
- m_part.ScheduleFullUpdate();
+ m_part.ScheduleFullUpdate();
- return type;
- }
- else
- {
- m_log.ErrorFormat(
- "[PRIM INVENTORY]: " +
- "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
- itemID, m_part.Name, m_part.UUID,
- m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
- }
+ return type;
+
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: " +
+ "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
+ itemID, m_part.Name, m_part.UUID,
+ m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
}
return -1;
@@ -763,52 +719,50 @@ namespace OpenSim.Region.Framework.Scenes
// isn't available (such as drag from prim inventory to agent inventory)
InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
- lock (m_items)
+ List items = GetInventoryItems();
+ foreach (TaskInventoryItem item in items)
{
- foreach (TaskInventoryItem item in m_items.Values)
- {
- UUID ownerID = item.OwnerID;
- uint everyoneMask = 0;
- uint baseMask = item.BasePermissions;
- uint ownerMask = item.CurrentPermissions;
- uint groupMask = item.GroupPermissions;
+ UUID ownerID = item.OwnerID;
+ uint everyoneMask = 0;
+ uint baseMask = item.BasePermissions;
+ uint ownerMask = item.CurrentPermissions;
+ uint groupMask = item.GroupPermissions;
- invString.AddItemStart();
- invString.AddNameValueLine("item_id", item.ItemID.ToString());
- invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
+ invString.AddItemStart();
+ invString.AddNameValueLine("item_id", item.ItemID.ToString());
+ invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
- invString.AddPermissionsStart();
+ invString.AddPermissionsStart();
- invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
- invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
- invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
- invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
- invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
+ invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
+ invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
+ invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
+ invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
+ invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
- invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
- invString.AddNameValueLine("owner_id", ownerID.ToString());
+ invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
+ invString.AddNameValueLine("owner_id", ownerID.ToString());
- invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
+ invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
- invString.AddNameValueLine("group_id", item.GroupID.ToString());
- invString.AddSectionEnd();
+ invString.AddNameValueLine("group_id", item.GroupID.ToString());
+ invString.AddSectionEnd();
- invString.AddNameValueLine("asset_id", item.AssetID.ToString());
- invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
- invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
- invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
+ invString.AddNameValueLine("asset_id", item.AssetID.ToString());
+ invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
+ invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
+ invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
- invString.AddSaleStart();
- invString.AddNameValueLine("sale_type", "not");
- invString.AddNameValueLine("sale_price", "0");
- invString.AddSectionEnd();
+ invString.AddSaleStart();
+ invString.AddNameValueLine("sale_type", "not");
+ invString.AddNameValueLine("sale_price", "0");
+ invString.AddSectionEnd();
- invString.AddNameValueLine("name", item.Name + "|");
- invString.AddNameValueLine("desc", item.Description + "|");
+ invString.AddNameValueLine("name", item.Name + "|");
+ invString.AddNameValueLine("desc", item.Description + "|");
- invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
- invString.AddSectionEnd();
- }
+ invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
+ invString.AddSectionEnd();
}
fileData = Utils.StringToBytes(invString.BuildString);
@@ -830,12 +784,10 @@ namespace OpenSim.Region.Framework.Scenes
{
if (HasInventoryChanged)
{
- lock (Items)
- {
- datastore.StorePrimInventory(m_part.UUID, Items.Values);
- }
-
HasInventoryChanged = false;
+ List items = GetInventoryItems();
+ datastore.StorePrimInventory(m_part.UUID, items);
+
}
}
@@ -1000,6 +952,30 @@ namespace OpenSim.Region.Framework.Scenes
return ret;
}
+
+ public List GetInventoryItems()
+ {
+ List ret = new List();
+
+ lock (m_items)
+ ret = new List(m_items.Values);
+
+ return ret;
+ }
+
+ public List GetInventoryScripts()
+ {
+ List ret = new List();
+
+ lock (m_items)
+ {
+ foreach (TaskInventoryItem item in m_items.Values)
+ if (item.InvType == (int)InventoryType.LSL)
+ ret.Add(item);
+ }
+
+ return ret;
+ }
public Dictionary GetScriptStates()
{
@@ -1009,24 +985,20 @@ namespace OpenSim.Region.Framework.Scenes
if (engines == null) // No engine at all
return ret;
- lock (m_items)
+ List scripts = GetInventoryScripts();
+
+ foreach (TaskInventoryItem item in scripts)
{
- foreach (TaskInventoryItem item in m_items.Values)
+ foreach (IScriptModule e in engines)
{
- if (item.InvType == (int)InventoryType.LSL)
+ if (e != null)
{
- foreach (IScriptModule e in engines)
+ string n = e.GetXMLState(item.ItemID);
+ if (n != String.Empty)
{
- if (e != null)
- {
- string n = e.GetXMLState(item.ItemID);
- if (n != String.Empty)
- {
- if (!ret.ContainsKey(item.ItemID))
- ret[item.ItemID] = n;
- break;
- }
- }
+ if (!ret.ContainsKey(item.ItemID))
+ ret[item.ItemID] = n;
+ break;
}
}
}
@@ -1041,25 +1013,22 @@ namespace OpenSim.Region.Framework.Scenes
if (engines == null)
return;
- lock (m_items)
+ List scripts = GetInventoryScripts();
+
+ foreach (TaskInventoryItem item in scripts)
{
- foreach (TaskInventoryItem item in m_items.Values)
+ foreach (IScriptModule engine in engines)
{
- if (item.InvType == (int)InventoryType.LSL)
+ if (engine != null)
{
- foreach (IScriptModule engine in engines)
- {
- if (engine != null)
- {
- if (item.OwnerChanged)
- engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
- item.OwnerChanged = false;
- engine.ResumeScript(item.ItemID);
- }
- }
+ if (item.OwnerChanged)
+ engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
+ item.OwnerChanged = false;
+ engine.ResumeScript(item.ItemID);
}
- }
+ }
}
}
+
}
}
--
cgit v1.1