Skip to content

Add state checks to Close() and Enqueue() #1029

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

Merged
merged 1 commit into from
Mar 2, 2020

Conversation

ricea
Copy link
Collaborator

@ricea ricea commented Feb 27, 2020

Exit early from abstract operations
ReadableStreamDefaultControllerClose() and
ReadableStreamDefaultControllerEnqueue() if
ReadableStreamDefaultControllerCanCloseOrEnqueue() is false. Remove the
asserts that it is true, and the requirement that callers perform the
check as part of the interface contract.

In practice the implementation of ReadableStreamTee() was failing to
properly check CanCloseOrEnqueue(). By relaxing the interface contract
we can prevent similar problems with future standards.

Also remove a now-redundant check of CanCloseOrEnqueue() in
TransformStreamDefaultControllerTerminate().

Also make similar changes to ReadableByteStreamControllerClose() and
ReadableByteStreamControllerEnqueue().


Preview | Diff

Exit early from abstract operations
ReadableStreamDefaultControllerClose() and
ReadableStreamDefaultControllerEnqueue() if
ReadableStreamDefaultControllerCanCloseOrEnqueue() is false. Remove the
asserts that it is true, and the requirement that callers perform the
check as part of the interface contract.

In practice the implementation of ReadableStreamTee() was failing to
properly check CanCloseOrEnqueue(). By relaxing the interface contract
we can prevent similar problems with future standards.

Also remove a now-redundant check of CanCloseOrEnqueue() in
TransformStreamDefaultControllerTerminate().

Also make similar changes to ReadableByteStreamControllerClose() and
ReadableByteStreamControllerEnqueue().
Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Tests?

@ricea
Copy link
Collaborator Author

ricea commented Mar 2, 2020

LGTM. Tests?

It doesn't appear to be possible to reproduce the problem with ReadableStreamTee() in a portable fashion. The logic only fails if microtasks can be made to run synchronously.

@ricea ricea merged commit a3e4822 into whatwg:master Mar 2, 2020
@ricea ricea deleted the enqueue-close-check-state branch March 2, 2020 08:49
@jswalden
Copy link

As best I understand things, microtasks shouldn't be able to be made to be run synchronously. If some spec is failing to properly defer a microtask checkpoint, that's just a bug in the spec. Or am I somehow wrong about this?

@ricea
Copy link
Collaborator Author

ricea commented Mar 11, 2020

As best I understand things, microtasks shouldn't be able to be made to be run synchronously. If some spec is failing to properly defer a microtask checkpoint, that's just a bug in the spec. Or am I somehow wrong about this?

This is how it's done in Chromium:

https://chromium.googlesource.com/chromium/src/+/12310ed05f15fea5fa6824c6a6b5d86f81532e25/third_party/blink/web_tests/http/tests/streams/chromium/concurrent-close.html

I don't know if that's a spec bug or an implementation bug.

@bzbarsky
Copy link

I don't know if that's a spec bug or an implementation bug.

Implementation bug. Per spec, that getter runs at https://heycam.github.io/webidl/#call-a-user-objects-operation step 10.1. But step 7 of that algorithm calls https://html.spec.whatwg.org/multipage/webappapis.html#prepare-to-run-script which pushes a JS execution context on the stack. After that, until the matching https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script (which happens in step 15.2), there should be no microtask checkpoints.

yutakahirano pushed a commit to yutakahirano/streams that referenced this pull request Jun 3, 2021
Exit early from abstract operations
ReadableStreamDefaultControllerClose() and
ReadableStreamDefaultControllerEnqueue() if
ReadableStreamDefaultControllerCanCloseOrEnqueue() is false. Remove the
asserts that it is true, and the requirement that callers perform the
check as part of the interface contract.

In practice the implementation of ReadableStreamTee() was failing to
properly check CanCloseOrEnqueue(). By relaxing the interface contract
we can prevent similar problems with future standards.

Also remove a now-redundant check of CanCloseOrEnqueue() in
TransformStreamDefaultControllerTerminate().

Also make similar changes to ReadableByteStreamControllerClose() and
ReadableByteStreamControllerEnqueue().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants