From d1147136946daf14724183b3191119be44ff8b16 Mon Sep 17 00:00:00 2001 From: CasperW Date: Tue, 24 Nov 2009 18:02:12 +0100 Subject: Drop all locking of part.TaskInventory in favour of a ReaderWriterLockSlim lock handler. This gives us: - Faster prim inventory actions. Multiple threads can read at once. - Fixes the known prim inventory thread locks - In the event of a thread lock occurring, it will usually self heal after sixty seconds with an error message in the console --- .../Shared/Api/Implementation/LSL_Api.cs | 532 ++++++++++++--------- .../Shared/Api/Implementation/OSSL_Api.cs | 36 +- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 22 +- 3 files changed, 334 insertions(+), 256 deletions(-) (limited to 'OpenSim/Region/ScriptEngine') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b549b5c..a94cd46 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -275,40 +275,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected UUID InventorySelf() { UUID invItemID = new UUID(); - - lock (m_host.TaskInventory) + bool unlock = false; + if (!m_host.TaskInventory.IsReadLockedByMe()) + { + m_host.TaskInventory.LockItemsForRead(true); + unlock = true; + } + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) { - if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) - { - invItemID = inv.Key; - break; - } + invItemID = inv.Key; + break; } } - + if (unlock) + { + m_host.TaskInventory.LockItemsForRead(false); + } return invItemID; } protected UUID InventoryKey(string name, int type) { m_host.AddScriptLPS(1); - - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == name) { - if (inv.Value.Name == name) + m_host.TaskInventory.LockItemsForRead(false); + + if (inv.Value.Type != type) { - if (inv.Value.Type != type) - return UUID.Zero; - - return inv.Value.AssetID; + return UUID.Zero; } + + return inv.Value.AssetID; } } + m_host.TaskInventory.LockItemsForRead(false); return UUID.Zero; } @@ -316,17 +324,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + + m_host.TaskInventory.LockItemsForRead(true); + + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == name) { - if (inv.Value.Name == name) - { - return inv.Value.AssetID; - } + m_host.TaskInventory.LockItemsForRead(false); + return inv.Value.AssetID; } } + m_host.TaskInventory.LockItemsForRead(false); + + return UUID.Zero; } @@ -2537,12 +2549,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); + m_host.TaskInventory.LockItemsForRead(true); TaskInventoryItem item = m_host.TaskInventory[invItemID]; - - lock (m_host.TaskInventory) - { - item = m_host.TaskInventory[invItemID]; - } + m_host.TaskInventory.LockItemsForRead(false); if (item.PermsGranter == UUID.Zero) return 0; @@ -2617,6 +2626,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (dist > m_ScriptDistanceFactor * 10.0f) return; + //Clone is thread-safe TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); foreach (KeyValuePair inv in partInventory) @@ -2750,13 +2760,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { TaskInventoryItem item; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + if (!m_host.TaskInventory.ContainsKey(InventorySelf())) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) - return; - else - item = m_host.TaskInventory[InventorySelf()]; + m_host.TaskInventory.LockItemsForRead(false); + return; + } + else + { + item = m_host.TaskInventory[InventorySelf()]; } + m_host.TaskInventory.LockItemsForRead(false); if (item.PermsGranter != UUID.Zero) { @@ -2778,13 +2792,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { TaskInventoryItem item; + m_host.TaskInventory.LockItemsForRead(true); lock (m_host.TaskInventory) { + if (!m_host.TaskInventory.ContainsKey(InventorySelf())) + { + m_host.TaskInventory.LockItemsForRead(false); return; + } else + { item = m_host.TaskInventory[InventorySelf()]; + } } + m_host.TaskInventory.LockItemsForRead(false); m_host.AddScriptLPS(1); @@ -2821,14 +2843,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api TaskInventoryItem item; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + + if (!m_host.TaskInventory.ContainsKey(InventorySelf())) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) - return; - else - item = m_host.TaskInventory[InventorySelf()]; + m_host.TaskInventory.LockItemsForRead(false); + return; + } + else + { + item = m_host.TaskInventory[InventorySelf()]; } + m_host.TaskInventory.LockItemsForRead(false); + if (item.PermsGranter != m_host.OwnerID) return; @@ -2853,13 +2881,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api TaskInventoryItem item; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + + if (!m_host.TaskInventory.ContainsKey(InventorySelf())) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) - return; - else - item = m_host.TaskInventory[InventorySelf()]; + m_host.TaskInventory.LockItemsForRead(false); + return; + } + else + { + item = m_host.TaskInventory[InventorySelf()]; } + m_host.TaskInventory.LockItemsForRead(false); + if (item.PermsGranter != m_host.OwnerID) return; @@ -3083,14 +3117,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api TaskInventoryItem item; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + if (!m_host.TaskInventory.ContainsKey(InventorySelf())) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) - return; - else - item = m_host.TaskInventory[InventorySelf()]; + m_host.TaskInventory.LockItemsForRead(false); + return; } - + else + { + item = m_host.TaskInventory[InventorySelf()]; + } + m_host.TaskInventory.LockItemsForRead(false); if (item.PermsGranter == UUID.Zero) return; @@ -3120,13 +3157,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api TaskInventoryItem item; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + if (!m_host.TaskInventory.ContainsKey(InventorySelf())) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) - return; - else - item = m_host.TaskInventory[InventorySelf()]; + m_host.TaskInventory.LockItemsForRead(false); + return; } + else + { + item = m_host.TaskInventory[InventorySelf()]; + } + m_host.TaskInventory.LockItemsForRead(false); + if (item.PermsGranter == UUID.Zero) return; @@ -3199,10 +3241,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api TaskInventoryItem item; - lock (m_host.TaskInventory) + + m_host.TaskInventory.LockItemsForRead(true); + if (!m_host.TaskInventory.ContainsKey(invItemID)) + { + m_host.TaskInventory.LockItemsForRead(false); + return; + } + else { item = m_host.TaskInventory[invItemID]; } + m_host.TaskInventory.LockItemsForRead(false); if (agentID == UUID.Zero || perm == 0) // Releasing permissions { @@ -3234,11 +3284,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms { - lock (m_host.TaskInventory) - { - m_host.TaskInventory[invItemID].PermsGranter = agentID; - m_host.TaskInventory[invItemID].PermsMask = perm; - } + m_host.TaskInventory.LockItemsForWrite(true); + m_host.TaskInventory[invItemID].PermsGranter = agentID; + m_host.TaskInventory[invItemID].PermsMask = perm; + m_host.TaskInventory.LockItemsForWrite(false); m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( "run_time_permissions", new Object[] { @@ -3258,11 +3307,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms { - lock (m_host.TaskInventory) - { - m_host.TaskInventory[invItemID].PermsGranter = agentID; - m_host.TaskInventory[invItemID].PermsMask = perm; - } + m_host.TaskInventory.LockItemsForWrite(true); + m_host.TaskInventory[invItemID].PermsGranter = agentID; + m_host.TaskInventory[invItemID].PermsMask = perm; + m_host.TaskInventory.LockItemsForWrite(false); m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( "run_time_permissions", new Object[] { @@ -3283,11 +3331,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!m_waitingForScriptAnswer) { - lock (m_host.TaskInventory) - { - m_host.TaskInventory[invItemID].PermsGranter = agentID; - m_host.TaskInventory[invItemID].PermsMask = 0; - } + m_host.TaskInventory.LockItemsForWrite(true); + m_host.TaskInventory[invItemID].PermsGranter = agentID; + m_host.TaskInventory[invItemID].PermsMask = 0; + m_host.TaskInventory.LockItemsForWrite(false); presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; m_waitingForScriptAnswer=true; @@ -3322,10 +3369,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) llReleaseControls(); - lock (m_host.TaskInventory) - { - m_host.TaskInventory[invItemID].PermsMask = answer; - } + + m_host.TaskInventory.LockItemsForWrite(true); + m_host.TaskInventory[invItemID].PermsMask = answer; + m_host.TaskInventory.LockItemsForWrite(false); + m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( "run_time_permissions", new Object[] { @@ -3337,16 +3385,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + if (item.Type == 10 && item.ItemID == m_itemID) { - if (item.Type == 10 && item.ItemID == m_itemID) - { - return item.PermsGranter.ToString(); - } + m_host.TaskInventory.LockItemsForRead(false); + return item.PermsGranter.ToString(); } } + m_host.TaskInventory.LockItemsForRead(false); return UUID.Zero.ToString(); } @@ -3355,19 +3404,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + if (item.Type == 10 && item.ItemID == m_itemID) { - if (item.Type == 10 && item.ItemID == m_itemID) - { - int perms = item.PermsMask; - if (m_automaticLinkPermission) - perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; - return perms; - } + int perms = item.PermsMask; + if (m_automaticLinkPermission) + perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; + m_host.TaskInventory.LockItemsForRead(false); + return perms; } } + m_host.TaskInventory.LockItemsForRead(false); return 0; } @@ -3400,11 +3450,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID invItemID = InventorySelf(); TaskInventoryItem item; - lock (m_host.TaskInventory) - { - item = m_host.TaskInventory[invItemID]; - } - + m_host.TaskInventory.LockItemsForRead(true); + item = m_host.TaskInventory[invItemID]; + m_host.TaskInventory.LockItemsForRead(false); + if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 && !m_automaticLinkPermission) { @@ -3457,16 +3506,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); UUID invItemID = InventorySelf(); - lock (m_host.TaskInventory) - { + m_host.TaskInventory.LockItemsForRead(true); if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 && !m_automaticLinkPermission) { ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); + m_host.TaskInventory.LockItemsForRead(false); return; } - } - + m_host.TaskInventory.LockItemsForRead(false); + if (linknum < ScriptBaseClass.LINK_THIS) return; @@ -3635,17 +3684,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); int count = 0; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Type == type || type == -1) { - if (inv.Value.Type == type || type == -1) - { - count = count + 1; - } + count = count + 1; } } - + + m_host.TaskInventory.LockItemsForRead(false); return count; } @@ -3654,16 +3702,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); ArrayList keys = new ArrayList(); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Type == type || type == -1) { - if (inv.Value.Type == type || type == -1) - { - keys.Add(inv.Value.Name); - } + keys.Add(inv.Value.Name); } } + m_host.TaskInventory.LockItemsForRead(false); if (keys.Count == 0) { @@ -3700,20 +3747,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // move the first object found with this inventory name - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == inventory) { - if (inv.Value.Name == inventory) - { - found = true; - objId = inv.Key; - assetType = inv.Value.Type; - objName = inv.Value.Name; - break; - } + found = true; + objId = inv.Key; + assetType = inv.Value.Type; + objName = inv.Value.Name; + break; } } + m_host.TaskInventory.LockItemsForRead(false); if (!found) { @@ -3763,20 +3809,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + if (item.Name == name) { - if (item.Name == name) - { - if (item.ItemID == m_itemID) - throw new ScriptDeleteException(); - else - m_host.Inventory.RemoveInventoryItem(item.ItemID); - return; - } + if (item.ItemID == m_itemID) + throw new ScriptDeleteException(); + else + m_host.Inventory.RemoveInventoryItem(item.ItemID); + + m_host.TaskInventory.LockItemsForRead(false); + return; } } + m_host.TaskInventory.LockItemsForRead(false); } public void llSetText(string text, LSL_Vector color, double alpha) @@ -3865,6 +3912,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); + //Clone is thread safe TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); foreach (TaskInventoryItem item in itemDictionary.Values) @@ -3955,17 +4003,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID soundId = UUID.Zero; if (!UUID.TryParse(impact_sound, out soundId)) { - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) { - if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) - { - soundId = item.AssetID; - break; - } + soundId = item.AssetID; + break; } } + m_host.TaskInventory.LockItemsForRead(false); } m_host.CollisionSound = soundId; m_host.CollisionSoundVolume = (float)impact_volume; @@ -4011,6 +4058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID partItemID; foreach (SceneObjectPart part in parts) { + //Clone is thread safe TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); foreach (TaskInventoryItem item in itemsDictionary.Values) @@ -4218,17 +4266,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + if (item.Type == 10 && item.ItemID == m_itemID) { - if (item.Type == 10 && item.ItemID == m_itemID) - { - result = item.Name!=null?item.Name:String.Empty; - break; - } + result = item.Name!=null?item.Name:String.Empty; + break; } } + m_host.TaskInventory.LockItemsForRead(false); return result; } @@ -4486,23 +4533,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == name) { - if (inv.Value.Name == name) + if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) { - if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) - { - return inv.Value.AssetID.ToString(); - } - else - { - return UUID.Zero.ToString(); - } + m_host.TaskInventory.LockItemsForRead(false); + return inv.Value.AssetID.ToString(); + } + else + { + m_host.TaskInventory.LockItemsForRead(false); + return UUID.Zero.ToString(); } } } + m_host.TaskInventory.LockItemsForRead(false); return UUID.Zero.ToString(); } @@ -5997,14 +6045,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected UUID GetTaskInventoryItem(string name) { - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == name) { - if (inv.Value.Name == name) - return inv.Key; + m_host.TaskInventory.LockItemsForRead(false); + return inv.Key; } } + m_host.TaskInventory.LockItemsForRead(false); return UUID.Zero; } @@ -6315,22 +6365,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // copy the first script found with this inventory name - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == name) { - if (inv.Value.Name == name) + // make sure the object is a script + if (10 == inv.Value.Type) { - // make sure the object is a script - if (10 == inv.Value.Type) - { - found = true; - srcId = inv.Key; - break; - } + found = true; + srcId = inv.Key; + break; } } } + m_host.TaskInventory.LockItemsForRead(false); if (!found) { @@ -8133,28 +8182,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == item) { - if (inv.Value.Name == item) + m_host.TaskInventory.LockItemsForRead(false); + switch (mask) { - switch (mask) - { - case 0: - return (int)inv.Value.BasePermissions; - case 1: - return (int)inv.Value.CurrentPermissions; - case 2: - return (int)inv.Value.GroupPermissions; - case 3: - return (int)inv.Value.EveryonePermissions; - case 4: - return (int)inv.Value.NextPermissions; - } + case 0: + return (int)inv.Value.BasePermissions; + case 1: + return (int)inv.Value.CurrentPermissions; + case 2: + return (int)inv.Value.GroupPermissions; + case 3: + return (int)inv.Value.EveryonePermissions; + case 4: + return (int)inv.Value.NextPermissions; } } } + m_host.TaskInventory.LockItemsForRead(false); return -1; } @@ -8169,16 +8218,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == item) { - if (inv.Value.Name == item) - { - return inv.Value.CreatorID.ToString(); - } + m_host.TaskInventory.LockItemsForRead(false); + return inv.Value.CreatorID.ToString(); } } + m_host.TaskInventory.LockItemsForRead(false); llSay(0, "No item name '" + item + "'"); @@ -8702,16 +8751,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == name) { - if (inv.Value.Name == name) - { - return inv.Value.Type; - } + m_host.TaskInventory.LockItemsForRead(false); + return inv.Value.Type; } } + m_host.TaskInventory.LockItemsForRead(false); return -1; } @@ -8742,17 +8791,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (invItemID == UUID.Zero) return new LSL_Vector(); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) { - if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) - return new LSL_Vector(); + m_host.TaskInventory.LockItemsForRead(false); + return new LSL_Vector(); + } - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) - { - ShoutError("No permissions to track the camera"); - return new LSL_Vector(); - } + if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) + { + ShoutError("No permissions to track the camera"); + m_host.TaskInventory.LockItemsForRead(false); + return new LSL_Vector(); } + m_host.TaskInventory.LockItemsForRead(false); ScenePresence presence = World.GetScenePresence(m_host.OwnerID); if (presence != null) @@ -8770,17 +8822,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (invItemID == UUID.Zero) return new LSL_Rotation(); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) { - if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) - return new LSL_Rotation(); - - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) - { - ShoutError("No permissions to track the camera"); - return new LSL_Rotation(); - } + m_host.TaskInventory.LockItemsForRead(false); + return new LSL_Rotation(); } + if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) + { + ShoutError("No permissions to track the camera"); + m_host.TaskInventory.LockItemsForRead(false); + return new LSL_Rotation(); + } + m_host.TaskInventory.LockItemsForRead(false); ScenePresence presence = World.GetScenePresence(m_host.OwnerID); if (presence != null) @@ -8930,14 +8984,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (objectID == UUID.Zero) return; UUID agentID; - lock (m_host.TaskInventory) - { - // we need the permission first, to know which avatar we want to set the camera for - agentID = m_host.TaskInventory[invItemID].PermsGranter; + m_host.TaskInventory.LockItemsForRead(true); + // we need the permission first, to know which avatar we want to set the camera for + agentID = m_host.TaskInventory[invItemID].PermsGranter; - if (agentID == UUID.Zero) return; - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; + if (agentID == UUID.Zero) + { + m_host.TaskInventory.LockItemsForRead(false); + return; + } + if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) + { + m_host.TaskInventory.LockItemsForRead(false); + return; } + m_host.TaskInventory.LockItemsForRead(false); ScenePresence presence = World.GetScenePresence(agentID); @@ -8987,12 +9048,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // we need the permission first, to know which avatar we want to clear the camera for UUID agentID; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + agentID = m_host.TaskInventory[invItemID].PermsGranter; + if (agentID == UUID.Zero) { - agentID = m_host.TaskInventory[invItemID].PermsGranter; - if (agentID == UUID.Zero) return; - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; + m_host.TaskInventory.LockItemsForRead(false); + return; } + if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) + { + m_host.TaskInventory.LockItemsForRead(false); + return; + } + m_host.TaskInventory.LockItemsForRead(false); ScenePresence presence = World.GetScenePresence(agentID); @@ -9449,15 +9517,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal UUID ScriptByName(string name) { - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + if (item.Type == 10 && item.Name == name) { - if (item.Type == 10 && item.Name == name) - return item.ItemID; + m_host.TaskInventory.LockItemsForRead(false); + return item.ItemID; } } + m_host.TaskInventory.LockItemsForRead(false); + return UUID.Zero; } @@ -9498,6 +9570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); + //Clone is thread safe TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); UUID assetID = UUID.Zero; @@ -9560,6 +9633,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); + //Clone is thread safe TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); UUID assetID = UUID.Zero; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 7fdbac8..83322eb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -728,18 +728,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (target != null) { UUID animID=UUID.Zero; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == animation) { - if (inv.Value.Name == animation) - { - if (inv.Value.Type == (int)AssetType.Animation) - animID = inv.Value.AssetID; - continue; - } + if (inv.Value.Type == (int)AssetType.Animation) + animID = inv.Value.AssetID; + continue; } } + m_host.TaskInventory.LockItemsForRead(false); if (animID == UUID.Zero) target.Animator.AddAnimation(animation, m_host.UUID); else @@ -761,18 +760,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (target != null) { UUID animID=UUID.Zero; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == animation) { - if (inv.Value.Name == animation) - { - if (inv.Value.Type == (int)AssetType.Animation) - animID = inv.Value.AssetID; - continue; - } + if (inv.Value.Type == (int)AssetType.Animation) + animID = inv.Value.AssetID; + continue; } } + m_host.TaskInventory.LockItemsForRead(false); if (animID == UUID.Zero) target.Animator.RemoveAnimation(animation); @@ -1541,6 +1539,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(name, out assetID)) { + m_host.TaskInventory.LockItemsForRead(true); foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { if (item.Type == 7 && item.Name == name) @@ -1548,6 +1547,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api assetID = item.AssetID; } } + m_host.TaskInventory.LockItemsForRead(false); } if (assetID == UUID.Zero) @@ -1594,6 +1594,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(name, out assetID)) { + m_host.TaskInventory.LockItemsForRead(true); foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { if (item.Type == 7 && item.Name == name) @@ -1601,6 +1602,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api assetID = item.AssetID; } } + m_host.TaskInventory.LockItemsForRead(false); } if (assetID == UUID.Zero) @@ -1651,6 +1653,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(name, out assetID)) { + m_host.TaskInventory.LockItemsForRead(true); foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { if (item.Type == 7 && item.Name == name) @@ -1658,6 +1661,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api assetID = item.AssetID; } } + m_host.TaskInventory.LockItemsForRead(false); } if (assetID == UUID.Zero) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 063d50f..0f4a9ad 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -238,13 +238,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance if (part != null) { - lock (part.TaskInventory) + part.TaskInventory.LockItemsForRead(true); + if (part.TaskInventory.ContainsKey(m_ItemID)) { - if (part.TaskInventory.ContainsKey(m_ItemID)) - { - m_thisScriptTask = part.TaskInventory[m_ItemID]; - } + m_thisScriptTask = part.TaskInventory[m_ItemID]; } + part.TaskInventory.LockItemsForRead(false); } ApiManager am = new ApiManager(); @@ -429,14 +428,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance { int permsMask; UUID permsGranter; - lock (part.TaskInventory) + part.TaskInventory.LockItemsForRead(true); + if (!part.TaskInventory.ContainsKey(m_ItemID)) { - if (!part.TaskInventory.ContainsKey(m_ItemID)) - return; - - permsGranter = part.TaskInventory[m_ItemID].PermsGranter; - permsMask = part.TaskInventory[m_ItemID].PermsMask; + part.TaskInventory.LockItemsForRead(false); + return; } + permsGranter = part.TaskInventory[m_ItemID].PermsGranter; + permsMask = part.TaskInventory[m_ItemID].PermsMask; + part.TaskInventory.LockItemsForRead(false); if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) { -- cgit v1.1