Skip to content

Commit

Permalink
Fix potential thread block in SingleCreationValueCache.GetOrAdd
Browse files Browse the repository at this point in the history
  • Loading branch information
Meivyn committed Aug 8, 2024
1 parent 80222a6 commit bd7245a
Showing 1 changed file with 17 additions and 5 deletions.
22 changes: 17 additions & 5 deletions IPA.Loader/Utilities/Async/SingleCreationValueCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public SingleCreationValueCache(IEnumerable<KeyValuePair<TKey, TValue>> collecti
#endregion

/// <summary>
/// Gets a value that indicates whether this cache is empty.
/// Gets a value that indicates whether this cache is empty.
/// </summary>
public bool IsEmpty => dict.IsEmpty;
/// <summary>
Expand Down Expand Up @@ -143,10 +143,22 @@ public TValue GetOrAdd(TKey key, Func<TKey, TValue> creator)
var cmp = (wh, default(TValue));
if (!dict.TryAdd(key, cmp))
goto retry; // someone else beat us to the punch, retry getting their value and wait for them
var val = creator(key);
while (!dict.TryUpdate(key, (null, val), cmp))
throw new InvalidOperationException();
wh.Set();
TValue val;
try
{
val = creator(key);
while (!dict.TryUpdate(key, (null, val), cmp))
throw new InvalidOperationException();
}
catch
{
dict.TryRemove(key, out _);
throw;
}
finally
{
wh.Set();
}
return val;
}
}
Expand Down

0 comments on commit bd7245a

Please sign in to comment.