Skip to content

Commit 38c05cf

Browse files
committed
Improved internal API to reuse it by AsyncEventHub
1 parent b647604 commit 38c05cf

File tree

1 file changed

+16
-29
lines changed

1 file changed

+16
-29
lines changed

src/DotNext.Threading/Threading/QueuedSynchronizer.cs

+16-29
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ private TNode EnqueueNode<TNode, TInitializer>(ref ValueTaskPool<bool, TNode, Ac
156156
private protected TNode EnqueueNode<TNode, TLockManager>(ref ValueTaskPool<bool, TNode, Action<TNode>> pool, WaitNodeFlags flags)
157157
where TNode : WaitNode, IPooledManualResetCompletionSource<Action<TNode>>, new()
158158
where TLockManager : struct, ILockManager<TNode>
159-
=> EnqueueNode<TNode, NodeInitializer<TNode, TLockManager>>(ref pool, new(flags));
159+
=> EnqueueNode<TNode, StaticInitializer<TNode, TLockManager>>(ref pool, new(flags));
160160

161161
private protected bool TryAcquire<TLockManager>(ref TLockManager manager)
162162
where TLockManager : struct, ILockManager
@@ -252,7 +252,7 @@ private protected ValueTask AcquireAsync<TNode, TLockManager, TOptions>(ref Valu
252252
where TNode : WaitNode, IPooledManualResetCompletionSource<Action<TNode>>, new()
253253
where TLockManager : struct, ILockManager<TNode>
254254
where TOptions : struct, IAcquisitionOptions
255-
=> AcquireAsync<ValueTask, TNode, NodeInitializer<TNode, TLockManager>, TLockManager, TOptions>(
255+
=> AcquireAsync<ValueTask, TNode, StaticInitializer<TNode, TLockManager>, TLockManager, TOptions>(
256256
ref pool,
257257
ref manager,
258258
new(WaitNodeFlags.ThrowOnTimeout),
@@ -263,32 +263,21 @@ private protected ValueTask<bool> TryAcquireAsync<TNode, TLockManager, TOptions>
263263
where TNode : WaitNode, IPooledManualResetCompletionSource<Action<TNode>>, new()
264264
where TLockManager : struct, ILockManager<TNode>
265265
where TOptions : struct, IAcquisitionOptions
266-
=> AcquireAsync<ValueTask<bool>, TNode, NodeInitializer<TNode, TLockManager>, TLockManager, TOptions>(
266+
=> AcquireAsync<ValueTask<bool>, TNode, StaticInitializer<TNode, TLockManager>, TLockManager, TOptions>(
267267
ref pool,
268268
ref manager,
269269
new(WaitNodeFlags.None),
270270
options);
271271

272-
private protected ValueTask AcquireAsync<TNode, TArg, TLockManager, TOptions>(ref ValueTaskPool<bool, TNode, Action<TNode>> pool,
273-
ref TLockManager manager, TArg arg, TOptions options)
274-
where TNode : WaitNode, IPooledManualResetCompletionSource<Action<TNode>>, new()
275-
where TLockManager : struct, ILockManager<TNode, TArg>
276-
where TOptions : struct, IAcquisitionOptions
277-
=> AcquireAsync<ValueTask, TNode, NodeInitializer<TNode, TArg, TLockManager>, TLockManager, TOptions>(
278-
ref pool,
279-
ref manager,
280-
new(WaitNodeFlags.ThrowOnTimeout, arg),
281-
options);
282-
283-
private protected ValueTask<bool> TryAcquireAsync<TNode, TArg, TLockManager, TOptions>(ref ValueTaskPool<bool, TNode, Action<TNode>> pool,
284-
ref TLockManager manager, TArg arg, TOptions options)
272+
private protected ValueTask AcquireSpecialAsync<TNode, TLockManager, TOptions>(ref ValueTaskPool<bool, TNode, Action<TNode>> pool,
273+
ref TLockManager manager, TOptions options)
285274
where TNode : WaitNode, IPooledManualResetCompletionSource<Action<TNode>>, new()
286-
where TLockManager : struct, ILockManager<TNode, TArg>
275+
where TLockManager : struct, ILockManager, IConsumer<TNode>
287276
where TOptions : struct, IAcquisitionOptions
288-
=> AcquireAsync<ValueTask<bool>, TNode, NodeInitializer<TNode, TArg, TLockManager>, TLockManager, TOptions>(
277+
=> AcquireAsync<ValueTask, TNode, NodeInitializer<TNode, TLockManager>, TLockManager, TOptions>(
289278
ref pool,
290279
ref manager,
291-
new(WaitNodeFlags.None, arg),
280+
new(WaitNodeFlags.ThrowOnTimeout, ref manager),
292281
options);
293282

294283
/// <summary>
@@ -458,7 +447,7 @@ private interface INodeInitializer<in TNode> : IConsumer<TNode>
458447
}
459448

460449
[StructLayout(LayoutKind.Auto)]
461-
private readonly struct NodeInitializer<TNode, TLockManager>(WaitNodeFlags flags) : INodeInitializer<TNode>
450+
private readonly struct StaticInitializer<TNode, TLockManager>(WaitNodeFlags flags) : INodeInitializer<TNode>
462451
where TNode : WaitNode
463452
where TLockManager : struct, ILockManager<TNode>
464453
{
@@ -467,14 +456,18 @@ private readonly struct NodeInitializer<TNode, TLockManager>(WaitNodeFlags flags
467456
void IConsumer<TNode>.Invoke(TNode node) => TLockManager.InitializeNode(node);
468457
}
469458

459+
// TODO: Replace with allows ref anti-constraint and ref struct
470460
[StructLayout(LayoutKind.Auto)]
471-
private readonly struct NodeInitializer<TNode, TArg, TLockManager>(WaitNodeFlags flags, TArg arg) : INodeInitializer<TNode>
461+
private readonly struct NodeInitializer<TNode, TLockManager>(WaitNodeFlags flags, ref TLockManager manager) : INodeInitializer<TNode>
472462
where TNode : WaitNode
473-
where TLockManager : struct, ILockManager<TNode, TArg>
463+
where TLockManager : struct, ILockManager, IConsumer<TNode>
474464
{
465+
private readonly unsafe void* managerOnStack = Unsafe.AsPointer(ref manager);
466+
475467
WaitNodeFlags INodeInitializer<TNode>.Flags => flags;
476468

477-
void IConsumer<TNode>.Invoke(TNode node) => TLockManager.InitializeNode(node, arg);
469+
unsafe void IConsumer<TNode>.Invoke(TNode node)
470+
=> Unsafe.AsRef<TLockManager>(managerOnStack).Invoke(node);
478471
}
479472

480473
private interface IValueTaskFactory<out T> : ISupplier<TimeSpan, CancellationToken, T>
@@ -574,12 +567,6 @@ static virtual void InitializeNode(TNode node)
574567
{
575568
}
576569
}
577-
578-
private protected interface ILockManager<in TNode, in TArg> : ILockManager
579-
where TNode : WaitNode
580-
{
581-
static abstract void InitializeNode(TNode node, TArg arg);
582-
}
583570

584571
/// <summary>
585572
/// Represents acquisition options.

0 commit comments

Comments
 (0)