From d93a442483a6afbcd85b881d2b168d25ac31f0ae 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') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3519d4b..20d5486 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); + } } @@ -1001,6 +953,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() { @@ -1010,24 +986,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; } } } @@ -1042,25 +1014,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