Skip to content

Commit bcad197

Browse files
committed
Returns the owned token if the source is not yet completed
1 parent 2302d5c commit bcad197

File tree

2 files changed

+16
-14
lines changed

2 files changed

+16
-14
lines changed

src/DotNext.Threading/Threading/CancellationTokenMultiplexer.Scope.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace DotNext.Threading;
77

88
using static Timeout;
9+
using MultiplexerOrToken = ValueTuple<object>;
910

1011
partial class CancellationTokenMultiplexer
1112
{
@@ -23,7 +24,7 @@ private interface IMultiplexedTokenScope : IMultiplexedCancellationTokenSource,
2324
// CancellationToken is just a wrapper over CancellationTokenSource.
2425
// For optimization purposes, if only one token is passed to the scope, we can inline the underlying CTS
2526
// to this structure.
26-
private readonly ValueTuple<object> multiplexerOrToken;
27+
private readonly MultiplexerOrToken multiplexerOrToken;
2728
private readonly PooledCancellationTokenSource? source;
2829

2930
internal Scope(CancellationTokenMultiplexer multiplexer, ReadOnlySpan<CancellationToken> tokens, bool timeoutSupport = false)
@@ -46,14 +47,14 @@ internal Scope(CancellationTokenMultiplexer multiplexer, TimeSpan timeout, ReadO
4647
internal Scope(CancellationToken token)
4748
=> multiplexerOrToken = InlineToken(token);
4849

49-
private static ValueTuple<object> InlineToken(CancellationToken token)
50+
private static MultiplexerOrToken InlineToken(CancellationToken token)
5051
=> LinkedCancellationTokenSource.CanInlineToken
51-
? Unsafe.BitCast<CancellationToken, ValueTuple<object>>(token)
52+
? Unsafe.BitCast<CancellationToken, MultiplexerOrToken>(token)
5253
: new(token);
5354

54-
private static CancellationToken GetToken(ValueTuple<object> value)
55+
private static CancellationToken GetToken(MultiplexerOrToken value)
5556
=> LinkedCancellationTokenSource.CanInlineToken
56-
? Unsafe.BitCast<ValueTuple<object>, CancellationToken>(value)
57+
? Unsafe.BitCast<MultiplexerOrToken, CancellationToken>(value)
5758
: (CancellationToken)value.Item1;
5859

5960
/// <inheritdoc cref="IMultiplexedCancellationTokenSource.Token"/>

src/DotNext.Threading/Threading/LinkedCancellationTokenSource.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace DotNext.Threading;
77

88
using Runtime;
9+
using InlinedToken = ValueTuple<object?>;
910

1011
/// <summary>
1112
/// Gets cancellation token source that allows to obtain the token that causes
@@ -18,7 +19,7 @@ namespace DotNext.Threading;
1819
public abstract class LinkedCancellationTokenSource : CancellationTokenSource, IMultiplexedCancellationTokenSource
1920
{
2021
// represents inlined CancellationToken
21-
private ValueTuple<object?> cancellationOrigin;
22+
private InlinedToken cancellationOrigin;
2223

2324
private protected LinkedCancellationTokenSource()
2425
{
@@ -36,8 +37,8 @@ static void OnCanceled(object? source, CancellationToken token)
3637
}
3738
}
3839

39-
private static ValueTuple<object?> InlineToken(CancellationToken token) => CanInlineToken
40-
? Unsafe.BitCast<CancellationToken, ValueTuple<object?>>(token)
40+
private static InlinedToken InlineToken(CancellationToken token) => CanInlineToken
41+
? Unsafe.BitCast<CancellationToken, InlinedToken>(token)
4142
: new(token);
4243

4344
internal void RegisterTimeoutHandler()
@@ -81,11 +82,11 @@ private bool TrySetCancellationOrigin(CancellationToken token)
8182
/// </remarks>
8283
public CancellationToken CancellationOrigin
8384
{
84-
get => CanInlineToken
85-
? Unsafe.BitCast<ValueTuple<object?>, CancellationToken>(cancellationOrigin)
86-
: cancellationOrigin.Item1 is null
87-
? CancellationToken.None
88-
: Unsafe.Unbox<CancellationToken>(cancellationOrigin.Item1);
85+
get => new InlinedToken(Volatile.Read(in cancellationOrigin.Item1)) is { Item1: not null } tokenCopy
86+
? CanInlineToken
87+
? Unsafe.BitCast<InlinedToken, CancellationToken>(tokenCopy)
88+
: Unsafe.Unbox<CancellationToken>(tokenCopy.Item1)
89+
: Token;
8990

9091
private protected set => cancellationOrigin = InlineToken(value);
9192
}
@@ -99,7 +100,7 @@ public CancellationToken CancellationOrigin
99100

100101
// This property checks whether the reinterpret cast CancellationToken => CancellationTokenSource
101102
// is safe. If not, just box the token.
102-
internal static bool CanInlineToken => Intrinsics.AreCompatible<CancellationToken, ValueTuple<object>>()
103+
internal static bool CanInlineToken => Intrinsics.AreCompatible<CancellationToken, InlinedToken>()
103104
&& RuntimeHelpers.IsReferenceOrContainsReferences<CancellationToken>();
104105

105106
internal static LinkedCancellationTokenSource? Combine(ref CancellationToken first, CancellationToken second)

0 commit comments

Comments
 (0)