From 720806b66183dc55589beb9161bdea071ac9c6fa Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 15 Jun 2013 00:34:45 +0100 Subject: Adjust the locking on InventoryCache. Locking for r/w of the ExpiringCache isn't needed since it's thread safe but r/w of contained dictionaries isn't thread-safe --- .../Inventory/InventoryCache.cs | 37 ++++++++++++++-------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs index 1e434b9..dcf33a1 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs @@ -1,11 +1,14 @@ using System; using System.Collections.Generic; - +using System.Threading; using OpenSim.Framework; using OpenMetaverse; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory { + /// + /// Cache root and system inventory folders to reduce number of potentially remote inventory calls and associated holdups. + /// public class InventoryCache { private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour @@ -16,8 +19,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory public void Cache(UUID userID, InventoryFolderBase root) { - lock (m_RootFolders) - m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS); + m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS); } public InventoryFolderBase GetRootFolder(UUID userID) @@ -31,14 +33,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory public void Cache(UUID userID, AssetType type, InventoryFolderBase folder) { - lock (m_FolderTypes) + Dictionary ff = null; + if (!m_FolderTypes.TryGetValue(userID, out ff)) + { + ff = new Dictionary(); + m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS); + } + + // We need to lock here since two threads could potentially retrieve the same dictionary + // and try to add a folder for that type simultaneously. Dictionary<>.Add() is not described as thread-safe in the SDK + // even if the folders are identical. + lock (ff) { - Dictionary ff = null; - if (!m_FolderTypes.TryGetValue(userID, out ff)) - { - ff = new Dictionary(); - m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS); - } if (!ff.ContainsKey(type)) ff.Add(type, folder); } @@ -50,8 +56,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory if (m_FolderTypes.TryGetValue(userID, out ff)) { InventoryFolderBase f = null; - if (ff.TryGetValue(type, out f)) - return f; + + lock (ff) + { + if (ff.TryGetValue(type, out f)) + return f; + } } return null; @@ -59,8 +69,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory public void Cache(UUID userID, InventoryCollection inv) { - lock (m_Inventories) - m_Inventories.AddOrUpdate(userID, inv, 120); + m_Inventories.AddOrUpdate(userID, inv, 120); } public InventoryCollection GetUserInventory(UUID userID) -- cgit v1.1 From ecfc6a3f4a44b70c3d7b3b03126f29f246136dfa Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 15 Jun 2013 00:36:04 +0100 Subject: Add the standard OpenSimulator copyright notice to the top of InventoryCache.cs --- .../Inventory/InventoryCache.cs | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs index dcf33a1..2fc8ee3 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs @@ -1,4 +1,31 @@ -using System; +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; using System.Collections.Generic; using System.Threading; using OpenSim.Framework; -- cgit v1.1