diff options
author | Justin Clark-Casey (justincc) | 2013-06-15 00:34:45 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2013-06-15 00:34:45 +0100 |
commit | 720806b66183dc55589beb9161bdea071ac9c6fa (patch) | |
tree | 3ed552e7836ad0f22d328b2de4e76f633371af1f | |
parent | minor: remove mono compiler warnings from LSL_Api, properly format method doc... (diff) | |
download | opensim-SC_OLD-720806b66183dc55589beb9161bdea071ac9c6fa.zip opensim-SC_OLD-720806b66183dc55589beb9161bdea071ac9c6fa.tar.gz opensim-SC_OLD-720806b66183dc55589beb9161bdea071ac9c6fa.tar.bz2 opensim-SC_OLD-720806b66183dc55589beb9161bdea071ac9c6fa.tar.xz |
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
-rw-r--r-- | OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs | 37 |
1 files changed, 23 insertions, 14 deletions
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 @@ | |||
1 | using System; | 1 | using System; |
2 | using System.Collections.Generic; | 2 | using System.Collections.Generic; |
3 | 3 | using System.Threading; | |
4 | using OpenSim.Framework; | 4 | using OpenSim.Framework; |
5 | using OpenMetaverse; | 5 | using OpenMetaverse; |
6 | 6 | ||
7 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | 7 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory |
8 | { | 8 | { |
9 | /// <summary> | ||
10 | /// Cache root and system inventory folders to reduce number of potentially remote inventory calls and associated holdups. | ||
11 | /// </summary> | ||
9 | public class InventoryCache | 12 | public class InventoryCache |
10 | { | 13 | { |
11 | private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour | 14 | private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour |
@@ -16,8 +19,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
16 | 19 | ||
17 | public void Cache(UUID userID, InventoryFolderBase root) | 20 | public void Cache(UUID userID, InventoryFolderBase root) |
18 | { | 21 | { |
19 | lock (m_RootFolders) | 22 | m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS); |
20 | m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS); | ||
21 | } | 23 | } |
22 | 24 | ||
23 | public InventoryFolderBase GetRootFolder(UUID userID) | 25 | public InventoryFolderBase GetRootFolder(UUID userID) |
@@ -31,14 +33,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
31 | 33 | ||
32 | public void Cache(UUID userID, AssetType type, InventoryFolderBase folder) | 34 | public void Cache(UUID userID, AssetType type, InventoryFolderBase folder) |
33 | { | 35 | { |
34 | lock (m_FolderTypes) | 36 | Dictionary<AssetType, InventoryFolderBase> ff = null; |
37 | if (!m_FolderTypes.TryGetValue(userID, out ff)) | ||
38 | { | ||
39 | ff = new Dictionary<AssetType, InventoryFolderBase>(); | ||
40 | m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS); | ||
41 | } | ||
42 | |||
43 | // We need to lock here since two threads could potentially retrieve the same dictionary | ||
44 | // and try to add a folder for that type simultaneously. Dictionary<>.Add() is not described as thread-safe in the SDK | ||
45 | // even if the folders are identical. | ||
46 | lock (ff) | ||
35 | { | 47 | { |
36 | Dictionary<AssetType, InventoryFolderBase> ff = null; | ||
37 | if (!m_FolderTypes.TryGetValue(userID, out ff)) | ||
38 | { | ||
39 | ff = new Dictionary<AssetType, InventoryFolderBase>(); | ||
40 | m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS); | ||
41 | } | ||
42 | if (!ff.ContainsKey(type)) | 48 | if (!ff.ContainsKey(type)) |
43 | ff.Add(type, folder); | 49 | ff.Add(type, folder); |
44 | } | 50 | } |
@@ -50,8 +56,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
50 | if (m_FolderTypes.TryGetValue(userID, out ff)) | 56 | if (m_FolderTypes.TryGetValue(userID, out ff)) |
51 | { | 57 | { |
52 | InventoryFolderBase f = null; | 58 | InventoryFolderBase f = null; |
53 | if (ff.TryGetValue(type, out f)) | 59 | |
54 | return f; | 60 | lock (ff) |
61 | { | ||
62 | if (ff.TryGetValue(type, out f)) | ||
63 | return f; | ||
64 | } | ||
55 | } | 65 | } |
56 | 66 | ||
57 | return null; | 67 | return null; |
@@ -59,8 +69,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
59 | 69 | ||
60 | public void Cache(UUID userID, InventoryCollection inv) | 70 | public void Cache(UUID userID, InventoryCollection inv) |
61 | { | 71 | { |
62 | lock (m_Inventories) | 72 | m_Inventories.AddOrUpdate(userID, inv, 120); |
63 | m_Inventories.AddOrUpdate(userID, inv, 120); | ||
64 | } | 73 | } |
65 | 74 | ||
66 | public InventoryCollection GetUserInventory(UUID userID) | 75 | public InventoryCollection GetUserInventory(UUID userID) |