@@ -108,6 +108,7 @@ const kWriteCb = 1 << 26;
108108const kExpectWriteCb = 1 << 27 ;
109109const kAfterWriteTickInfo = 1 << 28 ;
110110const kAfterWritePending = 1 << 29 ;
111+ const kIsDuplex = 1 << 30 ;
111112
112113// TODO(benjamingr) it is likely slower to do it this way than with free functions
113114function makeBitMapDescriptor ( bit ) {
@@ -286,6 +287,7 @@ function WritableState(options, stream, isDuplex) {
286287
287288 if ( options && options . objectMode ) this . state |= kObjectMode ;
288289 if ( isDuplex && options && options . writableObjectMode ) this . state |= kObjectMode ;
290+ if ( isDuplex ) this . state |= kIsDuplex ;
289291
290292 // The point at which write() starts returning false
291293 // Note: 0 is a valid value, means that we always return false if
@@ -513,13 +515,7 @@ function writeOrBuffer(stream, state, chunk, encoding, callback) {
513515
514516 state . length += len ;
515517
516- // stream._write resets state.length
517- const ret = state . length < state . highWaterMark ;
518-
519- // We must ensure that previous needDrain will not be reset to false.
520- if ( ! ret ) {
521- state . state |= kNeedDrain ;
522- }
518+ const prevLen = state . length ;
523519
524520 if ( ( state . state & ( kWriting | kErrored | kCorked | kConstructed ) ) !== kConstructed ) {
525521 state . buffered . push ( { chunk, encoding, callback } ) ;
@@ -539,6 +535,16 @@ function writeOrBuffer(stream, state, chunk, encoding, callback) {
539535 state . state &= ~ kSync ;
540536 }
541537
538+ const ret = (
539+ ( ( state . state & kIsDuplex ) === 0 || stream . _readableState . ended !== true ) ?
540+ state . length < state . highWaterMark :
541+ prevLen < state . highWaterMark
542+ ) ;
543+
544+ if ( ! ret ) {
545+ state . state |= kNeedDrain ;
546+ }
547+
542548 // Return false if errored or destroyed in order to break
543549 // any synchronous while(stream.write(data)) loops.
544550 return ret && ( state . state & ( kDestroyed | kErrored ) ) === 0 ;
0 commit comments