Fix race condition with cancellation tokens in Read/Flush operations (#59090)
authorDavid Fowler <davidfowl@gmail.com>
Wed, 15 Sep 2021 22:33:48 +0000 (15:33 -0700)
committerGitHub <noreply@github.com>
Wed, 15 Sep 2021 22:33:48 +0000 (15:33 -0700)
commit467f5c646be6895ee980321690296e61800c387b
treece70fe85200d0f7524625eeb3bd2fbefc76d0da6
parent965f95e9678de45faeb7c83b3bde3663277197c1
Fix race condition with cancellation tokens in Read/Flush operations (#59090)

* Fix race condition with cancellation tokens in Read/Write operations
- There's a tight race where UnsafeRegister can fire inline and then ReadAsync never completes. This is because the cancellation token property has not been assigned yet so the callback noops. This change checks the result of the UnsafeRegister operation to see if ran synchronously and throws if it did. We also move any state transitions to after these checks to make sure the PipeAwaitable state doesn't change before throwing.

* Add a debug assert to make sure there's no state change.

* Add if debug

* More if DEBUG
src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/PipeAwaitable.cs