Skip to content

Commit 5de25de

Browse files
authored
stream: avoid tick in writable hot path
PR-URL: #49966 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
1 parent 099e2f7 commit 5de25de

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

‎lib/internal/streams/writable.js‎

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -612,24 +612,31 @@ function onwrite(stream, er){
612612
}
613613

614614
if(sync){
615+
constneedDrain=state.length===0&&(state.state&kNeedDrain)!==0;
616+
constneedTick=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-
}elseif(state.afterWriteTickInfo!==null&&
627-
state.afterWriteTickInfo.cb===cb){
628-
state.afterWriteTickInfo.count++;
630+
}elseif((state.state&kAfterWriteTickInfo)!==0&&
631+
state[kAfterWriteTickInfoValue].cb===cb){
632+
state[kAfterWriteTickInfoValue].count++;
633+
}elseif(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

640647
functionafterWriteTick({ stream, state, count, cb }){
641-
state.afterWriteTickInfo=null;
648+
state.state&=~kAfterWriteTickInfo;
649+
state[kAfterWriteTickInfoValue]=null;
642650
returnafterWrite(stream,state,count,cb);
643651
}
644652

@@ -795,6 +803,8 @@ Writable.prototype.end = function(chunk, encoding, cb){
795803
if(typeofcb==='function'){
796804
if(err){
797805
process.nextTick(cb,err);
806+
}elseif((state.state&kErrored)!==0){
807+
process.nextTick(cb,state[kErroredValue]);
798808
}elseif((state.state&kFinished)!==0){
799809
process.nextTick(cb,null);
800810
}else{

0 commit comments

Comments
(0)