diff options
author | Robert Nagy <ronagy@icloud.com> | 2020-03-07 23:28:09 +0100 |
---|---|---|
committer | Robert Nagy <ronagy@icloud.com> | 2020-03-25 15:20:22 +0100 |
commit | 388cef61e8a4859b7505f7b5cf988eba27ce17b4 (patch) | |
tree | f59bbd98c1bb9f1c67f1ff95df616d3a2d674d05 /lib | |
parent | 05f1df520064475a255d8956f9e1b6f4bf4c8543 (diff) | |
download | node-new-388cef61e8a4859b7505f7b5cf988eba27ce17b4.tar.gz |
stream: align stream.Duplex with net.Socket
stream.Duplex and net.Socket slightly differs in behavior.
Especially when it comes to the case where one side never
becomes readable or writable. This aligns Duplex with the
behavior of Socket.
PR-URL: https://github.com/nodejs/node/pull/32139
Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/_stream_duplex.js | 16 | ||||
-rw-r--r-- | lib/_stream_readable.js | 21 | ||||
-rw-r--r-- | lib/_stream_writable.js | 10 |
3 files changed, 27 insertions, 20 deletions
diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js index b832c973a1..fe2281df47 100644 --- a/lib/_stream_duplex.js +++ b/lib/_stream_duplex.js @@ -66,7 +66,6 @@ function Duplex(options) { if (options.allowHalfOpen === false) { this.allowHalfOpen = false; - this.once('end', onend); } } } @@ -128,18 +127,3 @@ ObjectDefineProperties(Duplex.prototype, { } } }); - -// The no-half-open enforcer -function onend() { - // If the writable side ended, then we're ok. - if (this._writableState.ended) - return; - - // No more data can be written. - // But allow more writes to happen in this tick. - process.nextTick(onEndNT, this); -} - -function onEndNT(self) { - self.end(); -} diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index dfbd023d24..1df50ba200 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -1217,17 +1217,34 @@ function endReadableNT(state, stream) { state.endEmitted = true; stream.emit('end'); - if (state.autoDestroy) { + if (stream.writable && stream.allowHalfOpen === false) { + process.nextTick(endWritableNT, state, stream); + } else if (state.autoDestroy) { // In case of duplex streams we need a way to detect // if the writable side is ready for autoDestroy as well const wState = stream._writableState; - if (!wState || (wState.autoDestroy && wState.finished)) { + const autoDestroy = !wState || ( + wState.autoDestroy && + // We don't expect the writable to ever 'finish' + // if writable is explicitly set to false. + (wState.finished || wState.writable === false) + ); + + if (autoDestroy) { stream.destroy(); } } } } +function endWritableNT(state, stream) { + const writable = stream.writable && !stream.writableEnded && + !stream.destroyed; + if (writable) { + stream.end(); + } +} + Readable.from = function(iterable, opts) { if (from === undefined) { from = require('internal/streams/from'); diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index b24192101c..c3a7a35d2b 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -675,7 +675,13 @@ function finish(stream, state) { // In case of duplex streams we need a way to detect // if the readable side is ready for autoDestroy as well const rState = stream._readableState; - if (!rState || (rState.autoDestroy && rState.endEmitted)) { + const autoDestroy = !rState || ( + rState.autoDestroy && + // We don't expect the readable to ever 'end' + // if readable is explicitly set to false. + (rState.endEmitted || rState.readable === false) + ); + if (autoDestroy) { stream.destroy(); } } @@ -748,7 +754,7 @@ ObjectDefineProperties(Writable.prototype, { // Compat. The user might manually disable writable side through // deprecated setter. return !!w && w.writable !== false && !w.destroyed && !w.errored && - !w.ending; + !w.ending && !w.ended; }, set(val) { // Backwards compatible. |