修复相关漏洞
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
using System.Threading;
|
||||
|
||||
namespace SimpleAdmin.Application;
|
||||
|
||||
/// <summary>
|
||||
/// 使同一异步调用链可重入,独立请求仍须取得外部互斥锁。
|
||||
/// 不在 Acquire 中设置 AsyncLocal,避免值不能流回调用方的问题。
|
||||
/// </summary>
|
||||
internal static class OnboardingOperationGate
|
||||
{
|
||||
private sealed record Frame(string Key, Frame Parent);
|
||||
private static readonly AsyncLocal<Frame> Held = new();
|
||||
|
||||
internal static async Task<T> Run<T>(
|
||||
string key,
|
||||
Func<Task<IAsyncDisposable>> acquire,
|
||||
Func<Task<T>> action)
|
||||
{
|
||||
for (var frame = Held.Value; frame != null; frame = frame.Parent)
|
||||
if (frame.Key == key)
|
||||
return await action();
|
||||
|
||||
await using var lease = await acquire();
|
||||
var previous = Held.Value;
|
||||
Held.Value = new Frame(key, previous);
|
||||
try
|
||||
{
|
||||
return await action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Held.Value = previous;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user