Skip to content

Commit

Permalink
Keep ReadableStreamDefaultReader alive if it has pending requests.
Browse files Browse the repository at this point in the history
If the only reference to a ReadableStreamDefaultReader is from
javascript code that is used as fulfillment handler for its "read"
promise the reader can get garbage collected, resulting in the promise
never resolving. This fixes that issue by making
ReadableStreamDefaultReader implement HasPendingActivity to return true
if there are any pending read promises.

Bug: 1092048
Change-Id: Iccf2d6db453c6a27c82542af7a1dc1a2d792c3ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2561043
Reviewed-by: Adam Rice <ricea@chromium.org>
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#832599}
  • Loading branch information
mkruisselbrink authored and chromium-wpt-export-bot committed Dec 2, 2020
1 parent 44616b9 commit c56cc30
Showing 1 changed file with 15 additions and 5 deletions.
20 changes: 15 additions & 5 deletions FileAPI/blob/Blob-stream.any.js
Expand Up @@ -3,23 +3,33 @@
// META: script=../../streams/resources/test-utils.js
'use strict';

// Helper function that triggers garbage collection while reading a chunk
// if perform_gc is true.
async function read_and_gc(reader, perform_gc) {
const read_promise = reader.read();
if (perform_gc)
garbageCollect();
return read_promise;
}

// Takes in a ReadableStream and reads from it until it is done, returning
// an array that contains the results of each read operation
async function read_all_chunks(stream) {
// an array that contains the results of each read operation. If perform_gc
// is true, garbage collection is triggered while reading every chunk.
async function read_all_chunks(stream, perform_gc = false) {
assert_true(stream instanceof ReadableStream);
assert_true('getReader' in stream);
const reader = stream.getReader();

assert_true('read' in reader);
let read_value = await reader.read();
let read_value = await read_and_gc(reader, perform_gc);

let out = [];
let i = 0;
while (!read_value.done) {
for (let val of read_value.value) {
out[i++] = val;
}
read_value = await reader.read();
read_value = await read_and_gc(reader, perform_gc);
}
return out;
}
Expand Down Expand Up @@ -56,7 +66,7 @@ promise_test(async() => {
const stream = blob.stream();
blob = null;
garbageCollect();
const chunks = await read_all_chunks(stream);
const chunks = await read_all_chunks(stream, /*perform_gc=*/true);
assert_array_equals(chunks, input_arr);
}, "Blob.stream() garbage collection of blob shouldn't break stream" +
"consumption")

0 comments on commit c56cc30

Please sign in to comment.