@@ -612,24 +612,31 @@ function onwrite(stream, er) {
612612 }
613613
614614 if ( sync ) {
615+ const needDrain = state . length === 0 && ( state . state & kNeedDrain ) !== 0 ;
616+ const needTick = needDrain || ( state . state & kDestroyed !== 0 ) || cb !== nop ;
617+
615618 // It is a common case that the callback passed to .write() is always
616619 // the same. In that case, we do not schedule a new nextTick(), but
617620 // rather just increase a counter, to improve performance and avoid
618621 // memory allocations.
619622 if ( cb === nop ) {
620- if ( ( state . state & kAfterWritePending ) === 0 ) {
623+ if ( ( state . state & kAfterWritePending ) === 0 && needTick ) {
621624 process . nextTick ( afterWrite , stream , state , 1 , cb ) ;
622625 state . state |= kAfterWritePending ;
623626 } else {
624- state . pendingcb -= 1 ;
627+ state . pendingcb -- ;
628+ finishMaybe ( stream , state , true ) ;
625629 }
626- } else if ( state . afterWriteTickInfo !== null &&
627- state . afterWriteTickInfo . cb === cb ) {
628- state . afterWriteTickInfo . count ++ ;
630+ } else if ( ( state . state & kAfterWriteTickInfo ) !== 0 &&
631+ state [ kAfterWriteTickInfoValue ] . cb === cb ) {
632+ state [ kAfterWriteTickInfoValue ] . count ++ ;
633+ } else if ( needTick ) {
634+ state [ kAfterWriteTickInfoValue ] = { count : 1 , cb, stream, state } ;
635+ process . nextTick ( afterWriteTick , state [ kAfterWriteTickInfoValue ] ) ;
636+ state . state |= ( kAfterWritePending | kAfterWriteTickInfo ) ;
629637 } else {
630- state . afterWriteTickInfo = { count : 1 , cb, stream, state } ;
631- process . nextTick ( afterWriteTick , state . afterWriteTickInfo ) ;
632- state . state |= kAfterWritePending ;
638+ state . pendingcb -- ;
639+ finishMaybe ( stream , state , true ) ;
633640 }
634641 } else {
635642 afterWrite ( stream , state , 1 , cb ) ;
@@ -638,7 +645,8 @@ function onwrite(stream, er) {
638645}
639646
640647function afterWriteTick ( { stream, state, count, cb } ) {
641- state . afterWriteTickInfo = null ;
648+ state . state &= ~ kAfterWriteTickInfo ;
649+ state [ kAfterWriteTickInfoValue ] = null ;
642650 return afterWrite ( stream , state , count , cb ) ;
643651}
644652
@@ -795,6 +803,8 @@ Writable.prototype.end = function(chunk, encoding, cb) {
795803 if ( typeof cb === 'function' ) {
796804 if ( err ) {
797805 process . nextTick ( cb , err ) ;
806+ } else if ( ( state . state & kErrored ) !== 0 ) {
807+ process . nextTick ( cb , state [ kErroredValue ] ) ;
798808 } else if ( ( state . state & kFinished ) !== 0 ) {
799809 process . nextTick ( cb , null ) ;
800810 } else {
0 commit comments