diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index cfa36731e3d661..24f9b6bca83a9a 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -420,6 +420,11 @@ Readable.prototype.read = function(n) { n = parseInt(n, 10); } const state = this._readableState; + + if (state.destroyed) { + return; + } + const nOrig = n; // If we're asking for more than the current hwm, then raise the hwm. @@ -643,7 +648,7 @@ function maybeReadMore_(stream, state) { // called push() with new data. In this case we skip performing more // read()s. The execution ends in this method again after the _read() ends // up calling push() with more data. - while (!state.reading && !state.ended && + while (!state.reading && !state.ended && !state.destroyed && (state.length < state.highWaterMark || (state.flowing && state.length === 0))) { const len = state.length; @@ -976,6 +981,12 @@ function resume(stream, state) { function resume_(stream, state) { debug('resume', state.reading); + + if (state.destroyed) { + state.resumeScheduled = false; + return; + } + if (!state.reading) { stream.read(0); } diff --git a/test/parallel/test-stream-readable-destroy.js b/test/parallel/test-stream-readable-destroy.js index 05e7dd464ddca0..7687ea90cc82d8 100644 --- a/test/parallel/test-stream-readable-destroy.js +++ b/test/parallel/test-stream-readable-destroy.js @@ -189,3 +189,12 @@ const assert = require('assert'); read.push('hi'); read.on('data', common.mustNotCall()); } + +{ + const read = new Readable({ + read: common.mustNotCall(function() {}) + }); + read.destroy(); + assert.strictEqual(read.destroyed, true); + read.read(); +} diff --git a/test/parallel/test-stream-transform-destroy.js b/test/parallel/test-stream-transform-destroy.js index c594d9989ae4de..f6c4419aadf1a5 100644 --- a/test/parallel/test-stream-transform-destroy.js +++ b/test/parallel/test-stream-transform-destroy.js @@ -91,35 +91,6 @@ const assert = require('assert'); transform.destroy(); } -{ - const transform = new Transform({ - transform(chunk, enc, cb) {} - }); - transform.resume(); - - transform._destroy = common.mustCall(function(err, cb) { - assert.strictEqual(err, null); - process.nextTick(() => { - this.push(null); - this.end(); - cb(); - }); - }, 1); - - const fail = common.mustNotCall('no event'); - - transform.on('finish', fail); - transform.on('end', fail); - transform.on('close', common.mustCall()); - - transform.destroy(); - - transform.removeListener('end', fail); - transform.removeListener('finish', fail); - transform.on('end', common.mustCall()); - transform.on('finish', common.mustCall()); -} - { const transform = new Transform({ transform(chunk, enc, cb) {}