Skip to content

Commit 1e69695

Browse files
authored
Added missing locks and use timeout on all of them in ObjectCacheAppCache (#15902)
* Added missing locks, and ensure we have timeout on all of them * Wrap the removable of objects from the hashset in a lock * remove old comment * Exit correct lock
1 parent 39085b9 commit 1e69695

File tree

1 file changed

+45
-8
lines changed

1 file changed

+45
-8
lines changed

src/Umbraco.Core/Cache/ObjectCacheAppCache.cs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,10 @@ private IEnumerable<object> SearchByPredicate(Func<string, bool> predicate)
8888
object[] entries;
8989
try
9090
{
91-
_locker.EnterReadLock();
92-
91+
if (_locker.TryEnterReadLock(_readLockTimeout) is false)
92+
{
93+
throw new TimeoutException("Timeout exceeded to the memory cache when getting item");
94+
}
9395
entries = _keys.Where(predicate)
9496
.Select(key => MemoryCache.Get(key))
9597
.WhereNotNull()
@@ -125,11 +127,15 @@ private IEnumerable<object> SearchByPredicate(Func<string, bool> predicate)
125127
if (result == null || SafeLazy.GetSafeLazyValue(result, true) == null)
126128
{
127129
result = SafeLazy.GetSafeLazy(factory);
130+
128131
MemoryCacheEntryOptions options = GetOptions(timeout, isSliding);
129132

130133
try
131134
{
132-
_locker.EnterWriteLock();
135+
if (_locker.TryEnterWriteLock(_writeLockTimeout) is false)
136+
{
137+
throw new TimeoutException("Timeout exceeded to the memory cache when using factory to insert");
138+
}
133139

134140
// NOTE: This does an add or update
135141
MemoryCache.Set(key, result, options);
@@ -173,12 +179,26 @@ public void Insert(string key, Func<object?> factory, TimeSpan? timeout = null,
173179
{
174180
return; // do not store null values (backward compat)
175181
}
176-
177182
MemoryCacheEntryOptions options = GetOptions(timeout, isSliding);
178183

179-
// NOTE: This does an add or update
180-
MemoryCache.Set(key, result, options);
181-
_keys.Add(key);
184+
try
185+
{
186+
if (_locker.TryEnterWriteLock(_writeLockTimeout) is false)
187+
{
188+
throw new TimeoutException("Cannot insert value into cache, due to timeout for lock.");
189+
}
190+
191+
// NOTE: This does an add or update
192+
MemoryCache.Set(key, result, options);
193+
_keys.Add(key);
194+
}
195+
finally
196+
{
197+
if (_locker.IsWriteLockHeld)
198+
{
199+
_locker.ExitWriteLock();
200+
}
201+
}
182202
}
183203

184204
/// <inheritdoc />
@@ -348,6 +368,23 @@ private MemoryCacheEntryOptions GetOptions(TimeSpan? timeout = null, bool isSlid
348368
}
349369

350370
// Ensure key is removed from set when evicted from cache
351-
return options.RegisterPostEvictionCallback((key, _, _, _) => _keys.Remove((string)key));
371+
return options.RegisterPostEvictionCallback((key, _, _, _) =>
372+
{
373+
try
374+
{
375+
if (_locker.TryEnterWriteLock(_writeLockTimeout) is false)
376+
{
377+
throw new TimeoutException("Timeout exceeded to the memory cache when using factory to insert");
378+
}
379+
_keys.Remove((string)key);
380+
}
381+
finally
382+
{
383+
if (_locker.IsWriteLockHeld)
384+
{
385+
_locker.ExitWriteLock();
386+
}
387+
}
388+
});
352389
}
353390
}

0 commit comments

Comments
 (0)