Browse Source

Fix potential thread block in `SingleCreationValueCache.GetOrAdd`

master
Meivyn 3 months ago
parent
commit
bd7245aecb
No known key found for this signature in database GPG Key ID: 8BDD3E48158B2F71
1 changed files with 17 additions and 5 deletions
  1. +17
    -5
      IPA.Loader/Utilities/Async/SingleCreationValueCache.cs

+ 17
- 5
IPA.Loader/Utilities/Async/SingleCreationValueCache.cs View File

@ -71,7 +71,7 @@ namespace IPA.Utilities.Async
#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>
@ -143,10 +143,22 @@ namespace IPA.Utilities.Async
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;
}
}


Loading…
Cancel
Save