@@ -108,6 +108,7 @@ const kWriteCb = 1 << 26;
108
108
const kExpectWriteCb = 1 << 27 ;
109
109
const kAfterWriteTickInfo = 1 << 28 ;
110
110
const kAfterWritePending = 1 << 29 ;
111
+ const kHasBuffer = 1 << 30 ;
111
112
112
113
// TODO(benjamingr) it is likely slower to do it this way than with free functions
113
114
function makeBitMapDescriptor ( bit ) {
@@ -340,6 +341,7 @@ function resetBuffer(state) {
340
341
state . buffered = [ ] ;
341
342
state . bufferedIndex = 0 ;
342
343
state . state |= kAllBuffers | kAllNoop ;
344
+ state . state &= ~ kHasBuffer ;
343
345
}
344
346
345
347
WritableState . prototype . getBuffer = function getBuffer ( ) {
@@ -396,11 +398,13 @@ function Writable(options) {
396
398
destroyImpl . construct ( this , ( ) => {
397
399
const state = this . _writableState ;
398
400
399
- if ( ! state . writing ) {
401
+ if ( ( state . state & kWriting ) === 0 ) {
400
402
clearBuffer ( this , state ) ;
401
403
}
402
404
403
- finishMaybe ( this , state ) ;
405
+ if ( ( state . state & kEnding ) !== 0 ) {
406
+ finishMaybe ( this , state ) ;
407
+ }
404
408
} ) ;
405
409
}
406
410
@@ -523,6 +527,7 @@ function writeOrBuffer(stream, state, chunk, encoding, callback) {
523
527
524
528
if ( ( state . state & ( kWriting | kErrored | kCorked | kConstructed ) ) !== kConstructed ) {
525
529
state . buffered . push ( { chunk, encoding, callback } ) ;
530
+ state . state |= kHasBuffer ;
526
531
if ( ( state . state & kAllBuffers ) !== 0 && encoding !== 'buffer' ) {
527
532
state . state &= ~ kAllBuffers ;
528
533
}
@@ -591,8 +596,9 @@ function onwrite(stream, er) {
591
596
// Avoid V8 leak, https://github.com/nodejs/node/pull/34103#issuecomment-652002364
592
597
er . stack ; // eslint-disable-line no-unused-expressions
593
598
594
- if ( ! state . errored ) {
595
- state . errored = er ;
599
+ if ( ( state . state & kErrored ) === 0 ) {
600
+ state [ kErroredValue ] = er ;
601
+ state . state |= kErrored ;
596
602
}
597
603
598
604
// In case of duplex streams we need to notify the readable side of the
@@ -607,12 +613,12 @@ function onwrite(stream, er) {
607
613
onwriteError ( stream , state , er , cb ) ;
608
614
}
609
615
} else {
610
- if ( state . buffered . length > state . bufferedIndex ) {
616
+ if ( ( state . state & kHasBuffer ) !== 0 ) {
611
617
clearBuffer ( stream , state ) ;
612
618
}
613
619
614
620
if ( sync ) {
615
- const needDrain = state . length === 0 && ( state . state & kNeedDrain ) ! == 0 ;
621
+ const needDrain = ( state . state & kNeedDrain ) !== 0 && state . length = == 0 ;
616
622
const needTick = needDrain || ( state . state & kDestroyed !== 0 ) || cb !== nop ;
617
623
618
624
// It is a common case that the callback passed to .write() is always
@@ -625,7 +631,9 @@ function onwrite(stream, er) {
625
631
state . state |= kAfterWritePending ;
626
632
} else {
627
633
state . pendingcb -- ;
628
- finishMaybe ( stream , state , true ) ;
634
+ if ( ( state . state & kEnding ) !== 0 ) {
635
+ finishMaybe ( stream , state , true ) ;
636
+ }
629
637
}
630
638
} else if ( ( state . state & kAfterWriteTickInfo ) !== 0 &&
631
639
state [ kAfterWriteTickInfoValue ] . cb === cb ) {
@@ -636,7 +644,9 @@ function onwrite(stream, er) {
636
644
state . state |= ( kAfterWritePending | kAfterWriteTickInfo ) ;
637
645
} else {
638
646
state . pendingcb -- ;
639
- finishMaybe ( stream , state , true ) ;
647
+ if ( ( state . state & kEnding ) !== 0 ) {
648
+ finishMaybe ( stream , state , true ) ;
649
+ }
640
650
}
641
651
} else {
642
652
afterWrite ( stream , state , 1 , cb ) ;
@@ -668,7 +678,9 @@ function afterWrite(stream, state, count, cb) {
668
678
errorBuffer ( state ) ;
669
679
}
670
680
671
- finishMaybe ( stream , state ) ;
681
+ if ( ( state . state & kEnding ) !== 0 ) {
682
+ finishMaybe ( stream , state , true ) ;
683
+ }
672
684
}
673
685
674
686
// If there's something in the buffer waiting, then invoke callbacks.
@@ -692,7 +704,7 @@ function errorBuffer(state) {
692
704
693
705
// If there's something in the buffer waiting, then process it.
694
706
function clearBuffer ( stream , state ) {
695
- if ( ( state . state & ( kDestroyed | kBufferProcessing | kCorked ) ) !== 0 ||
707
+ if ( ( state . state & ( kDestroyed | kBufferProcessing | kCorked | kHasBuffer ) ) !== kHasBuffer ||
696
708
( state . state & kConstructed ) === 0 ) {
697
709
return ;
698
710
}
0 commit comments