diff options
author | Robert Nagy <ronagy@icloud.com> | 2019-12-20 15:49:24 +0100 |
---|---|---|
committer | Ruben Bridgewater <ruben@bridgewater.de> | 2019-12-25 12:12:59 +0100 |
commit | 3d47c8592d179991d3bfa4902f12c4fce07ac2d3 (patch) | |
tree | a98724f49bcad938eb896827ed94e3b56966ce76 /lib/_stream_readable.js | |
parent | cd6b00df3376d23643467b4c53e2e93bd9c28ce6 (diff) | |
download | node-new-3d47c8592d179991d3bfa4902f12c4fce07ac2d3.tar.gz |
stream: reset flowing state if no 'readable' or 'data' listeners
If we don't have any 'readable' or 'data' listeners and we are
not about to resume. Then reset flowing state to initial null state.
PR-URL: https://github.com/nodejs/node/pull/31036
Fixes: https://github.com/nodejs/node/issues/24474
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'lib/_stream_readable.js')
-rw-r--r-- | lib/_stream_readable.js | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 63efff4037..bda03cc152 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -28,6 +28,7 @@ const { ObjectDefineProperty, ObjectSetPrototypeOf, SymbolAsyncIterator, + Symbol } = primordials; module.exports = Readable; @@ -51,6 +52,8 @@ const { ERR_STREAM_UNSHIFT_AFTER_END_EVENT } = require('internal/errors').codes; +const kPaused = Symbol('kPaused'); + // Lazy loaded to improve the startup performance. let StringDecoder; let createReadableStreamAsyncIterator; @@ -126,7 +129,7 @@ function ReadableState(options, stream, isDuplex) { this.emittedReadable = false; this.readableListening = false; this.resumeScheduled = false; - this.paused = true; + this[kPaused] = null; // True if the error was already emitted and should not be thrown again this.errorEmitted = false; @@ -173,6 +176,16 @@ ObjectDefineProperty(ReadableState.prototype, 'pipesCount', { } }); +// Legacy property for `paused` +ObjectDefineProperty(ReadableState.prototype, 'paused', { + get() { + return this[kPaused] !== false; + }, + set(value) { + this[kPaused] = !!value; + } +}); + function Readable(options) { if (!(this instanceof Readable)) return new Readable(options); @@ -368,7 +381,8 @@ function chunkInvalid(state, chunk) { Readable.prototype.isPaused = function() { - return this._readableState.flowing === false; + const state = this._readableState; + return state[kPaused] === true || state.flowing === false; }; // Backwards compatibility. @@ -967,7 +981,7 @@ function updateReadableListening(self) { const state = self._readableState; state.readableListening = self.listenerCount('readable') > 0; - if (state.resumeScheduled && !state.paused) { + if (state.resumeScheduled && state[kPaused] === false) { // Flowing needs to be set to true now, otherwise // the upcoming resume will not flow. state.flowing = true; @@ -975,6 +989,8 @@ function updateReadableListening(self) { // Crude way to check if we should resume } else if (self.listenerCount('data') > 0) { self.resume(); + } else if (!state.readableListening) { + state.flowing = null; } } @@ -995,7 +1011,7 @@ Readable.prototype.resume = function() { state.flowing = !state.readableListening; resume(this, state); } - state.paused = false; + state[kPaused] = false; return this; }; @@ -1026,7 +1042,7 @@ Readable.prototype.pause = function() { this._readableState.flowing = false; this.emit('pause'); } - this._readableState.paused = true; + this._readableState[kPaused] = true; return this; }; |