Skip to content

Commit 2ec981b

Browse files
addaleaxMylesBorins
authored andcommitted
process: use more direct sync I/O for stdio
This avoids routing writes through the full LibuvStreamWrap write machinery. In particular, it enables the next commit, because otherwise the callback passed to `_write()` would not be called synchronously for pipes on Windows (because the latter does not support `uv_try_write()`, even for blocking I/O). PR-URL: #18019 Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent 69efa9f commit 2ec981b

3 files changed

Lines changed: 39 additions & 4 deletions

File tree

‎lib/internal/net.js‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
'use strict';
22

3+
constBuffer=require('buffer').Buffer;
4+
const{ writeBuffer }=process.binding('fs');
5+
36
// Check that the port number is not NaN when coerced to a number,
47
// is an integer and that it falls within the legal range of port numbers.
58
functionisLegalPort(port){
@@ -9,7 +12,28 @@ function isLegalPort(port) {
912
return+port===(+port>>>0)&&port<=0xFFFF;
1013
}
1114

15+
functionmakeSyncWrite(fd){
16+
returnfunction(chunk,enc,cb){
17+
if(enc!=='buffer')
18+
chunk=Buffer.from(chunk,enc);
19+
20+
this._bytesDispatched+=chunk.length;
21+
22+
try{
23+
writeBuffer(fd,chunk,0,chunk.length,null);
24+
}catch(ex){
25+
// Legacy: net writes have .code === .errno, whereas writeBuffer gives the
26+
// raw errno number in .errno.
27+
if(typeofex.code==='string')
28+
ex.errno=ex.code;
29+
returncb(ex);
30+
}
31+
cb();
32+
};
33+
}
34+
1235
module.exports={
1336
isLegalPort,
37+
makeSyncWrite,
1438
normalizedArgsSymbol: Symbol('normalizedArgs')
1539
};

‎lib/net.js‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@ const stream = require('stream');
2626
consttimers=require('timers');
2727
constutil=require('util');
2828
constinternalUtil=require('internal/util');
29-
const{ isLegalPort, normalizedArgsSymbol }=require('internal/net');
29+
const{
30+
isLegalPort,
31+
normalizedArgsSymbol,
32+
makeSyncWrite
33+
}=require('internal/net');
3034
constassert=require('assert');
3135
constcares=process.binding('cares_wrap');
3236
constuv=process.binding('uv');
@@ -206,20 +210,24 @@ function Socket(options) {
206210
this._handle=options.handle;// private
207211
this[async_id_symbol]=getNewAsyncId(this._handle);
208212
}elseif(options.fd!==undefined){
209-
this._handle=createHandle(options.fd,false);
210-
this._handle.open(options.fd);
213+
constfd=options.fd;
214+
this._handle=createHandle(fd,false);
215+
this._handle.open(fd);
211216
this[async_id_symbol]=this._handle.getAsyncId();
212217
// options.fd can be string (since it is user-defined),
213218
// so changing this to === would be semver-major
214219
// See: https://github.com/nodejs/node/pull/11513
215220
// eslint-disable-next-line eqeqeq
216-
if((options.fd==1||options.fd==2)&&
221+
if((fd==1||fd==2)&&
217222
(this._handleinstanceofPipe)&&
218223
process.platform==='win32'){
219224
// Make stdout and stderr blocking on Windows
220225
varerr=this._handle.setBlocking(true);
221226
if(err)
222227
throwerrnoException(err,'setBlocking');
228+
229+
this._writev=null;
230+
this._write=makeSyncWrite(fd);
223231
}
224232
this.readable=options.readable!==false;
225233
this.writable=options.writable!==false;

‎lib/tty.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
const{ inherits, _extend }=require('util');
2525
constnet=require('net');
2626
const{TTY, isTTY }=process.binding('tty_wrap');
27+
const{ makeSyncWrite }=require('internal/net');
2728
consterrors=require('internal/errors');
2829
constreadline=require('readline');
2930

@@ -77,6 +78,8 @@ function WriteStream(fd) {
7778
// even though it was originally intended to change in v1.0.2 (Libuv 1.2.1).
7879
// Ref: https://github.com/nodejs/node/pull/1771#issuecomment-119351671
7980
this._handle.setBlocking(true);
81+
this._writev=null;
82+
this._write=makeSyncWrite(fd);
8083

8184
varwinSize=newArray(2);
8285
varerr=this._handle.getWindowSize(winSize);

0 commit comments

Comments
 (0)