@@ -396,7 +396,7 @@ function Writable(options) {
396
396
destroyImpl . construct ( this , ( ) => {
397
397
const state = this . _writableState ;
398
398
399
- if ( ! state . writing ) {
399
+ if ( ( state . state & kWriting ) === 0 ) {
400
400
clearBuffer ( this , state ) ;
401
401
}
402
402
@@ -612,24 +612,30 @@ function onwrite(stream, er) {
612
612
}
613
613
614
614
if ( sync ) {
615
+ const needDrain = ( state . state & kNeedDrain ) !== 0 && state . length === 0 ;
616
+ const needTick = needDrain || ( state . state & kDestroyed !== 0 ) || cb !== nop ;
617
+
615
618
// It is a common case that the callback passed to .write() is always
616
619
// the same. In that case, we do not schedule a new nextTick(), but
617
620
// rather just increase a counter, to improve performance and avoid
618
621
// memory allocations.
619
622
if ( cb === nop ) {
620
- if ( ( state . state & kAfterWritePending ) === 0 ) {
623
+ if ( ( state . state & kAfterWritePending ) === 0 && needTick ) {
621
624
process . nextTick ( afterWrite , stream , state , 1 , cb ) ;
622
625
state . state |= kAfterWritePending ;
623
626
} else {
624
627
state . pendingcb -= 1 ;
625
628
}
626
- } else if ( state . afterWriteTickInfo !== null &&
627
- state . afterWriteTickInfo . cb === cb ) {
628
- state . afterWriteTickInfo . count ++ ;
629
+ } else if ( ( state . state & kAfterWriteTickInfo ) !== 0 &&
630
+ state [ kAfterWriteTickInfoValue ] . cb === cb ) {
631
+ state [ kAfterWriteTickInfoValue ] . count ++ ;
632
+ } else if ( needTick ) {
633
+ state [ kAfterWriteTickInfoValue ] = { count : 1 , cb, stream, state } ;
634
+ process . nextTick ( afterWriteTick , state [ kAfterWriteTickInfoValue ] ) ;
635
+ state . state |= ( kAfterWritePending | kAfterWriteTickInfo ) ;
629
636
} else {
630
- state . afterWriteTickInfo = { count : 1 , cb, stream, state } ;
631
- process . nextTick ( afterWriteTick , state . afterWriteTickInfo ) ;
632
- state . state |= kAfterWritePending ;
637
+ state . pendingcb -- ;
638
+ finishMaybe ( stream , state , true ) ;
633
639
}
634
640
} else {
635
641
afterWrite ( stream , state , 1 , cb ) ;
@@ -638,7 +644,8 @@ function onwrite(stream, er) {
638
644
}
639
645
640
646
function afterWriteTick ( { stream, state, count, cb } ) {
641
- state . afterWriteTickInfo = null ;
647
+ state . state &= ~ kAfterWriteTickInfo ;
648
+ state [ kAfterWriteTickInfoValue ] = null ;
642
649
return afterWrite ( stream , state , count , cb ) ;
643
650
}
644
651
@@ -795,6 +802,8 @@ Writable.prototype.end = function(chunk, encoding, cb) {
795
802
if ( typeof cb === 'function' ) {
796
803
if ( err ) {
797
804
process . nextTick ( cb , err ) ;
805
+ } else if ( ( state . state & kErrored ) !== 0 ) {
806
+ process . nextTick ( cb , state [ kErroredValue ] ) ;
798
807
} else if ( ( state . state & kFinished ) !== 0 ) {
799
808
process . nextTick ( cb , null ) ;
800
809
} else {
0 commit comments