Skip to content

Commit

Permalink
lib: ensure readable stream flows to end
Browse files Browse the repository at this point in the history
If a readable stream was set up with `highWaterMark 0`, the while-loop
in `maybeReadMore_` function would never execute.

The while loop now has an extra or-condition for the case where the
stream is flowing and there are no items. The or-condition is adapted
from the emit-condition of the `addChunk` function.

The `addChunk` also contains a check for `state.sync`. However that part
of the check was omitted here because the `maybeReadMore_` is executed
using `process.nextTick`. `state.sync` is set and then unset  within the
`read()` function so it should never be in effect in `maybeReadMore_`.

Fixes: nodejs#24915
  • Loading branch information
Rantanen committed Dec 9, 2018
1 parent 951b1c3 commit 6685360
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/_stream_readable.js
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,8 @@ function maybeReadMore(stream, state) {
function maybeReadMore_(stream, state) {
var len = state.length;
while (!state.reading && !state.ended &&
state.length < state.highWaterMark) {
(state.length < state.highWaterMark ||
state.flowing && state.length === 0)) {
debug('maybeReadMore read 0');
stream.read(0);
if (len === state.length)
Expand Down
27 changes: 27 additions & 0 deletions test/parallel/test-stream-readable-hwm-0-async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict';

const common = require('../common');

// This test ensures that Readable stream will call _read() for streams
// with highWaterMark === 0 upon .read(0) instead of just trying to
// emit 'readable' event.

const { Readable } = require('stream');

let count = 5;

const r = new Readable({
// Called 6 times: First 5 return data, last one signals end of stream.
read: common.mustCall(() => {
process.nextTick(common.mustCall(() => {
if (count--)
r.push('a');
else
r.push(null);
}));
}, 6),
highWaterMark: 0,
});

r.on('end', common.mustCall());
r.on('data', common.mustCall(5));

0 comments on commit 6685360

Please sign in to comment.