-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CancellationTokenSource.TryReset #50346
Conversation
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
Trying to wrap my mind around what happens if we have a linked CTS (via CancellationToken parent1 = GetToken();
CancellationToken parent2 = GetToken();
CancellationTokenSource child = CancellationTokenSource.CreateLinkedTokenSource(parent1, parent2); From reading through this code, it looks like if either parent1's CTS or parent2's CTS is reset, then that particular token tripping will no longer trigger the child being canceled, but the other token can still trigger a cancellation. That seems fine. But what happens if somebody calls child.TryReset()? It clears any registrations tied directly to it, but it's still listening for cancellation notifications coming from its parents, correct? What I'm trying to figure out is how the phrase "usage of TryReset concurrently with issuing cancellation is not thread-safe" squares with the fact that we might have a linked CTS. Since I assume most linked CTS instances don't "own" the parent and can't control when the parent triggers cancellation, it would be ill-advised to call TryReset on a CTS returned by the CreateLinkedTokenSource API? |
src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs
Outdated
Show resolved
Hide resolved
Correct. If you have: var cts2 = CreateLinkedTokenSource(cts1.Token); then this is basically the same as: var cts2 = new CancellationTokenSource();
cts2._registrationToDispose = cts1.Token.Register(() => cts2.Cancel()); So if you call cts1.TryReset, it'll drop the registration to call cts2.Cancel, and if cts1 has cancellation requested, it won't forward that along to cts2.
Correct
Right. It's no different than if you handed out a reference to your CTS to someone else that might call Cancel{After}. You're no longer the sole owner, and so using TryReset is problematic. You won't corrupt the instance, but you might return true even if the CTS is already canceled. |
That seems fine then. A race condition is much preferred to corruption. :) |
I'll augment the comment to clarify. Thanks. |
src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs
Outdated
Show resolved
Hide resolved
…ellationTokenSource.cs
It's time ❗ |
Fixes #48492