Skip to content

Commit 975ec4a

Browse files
author
pluris
committed
fs: improve error performance for writeSync
1 parent 8e7da60 commit 975ec4a

File tree

5 files changed

+79
-27
lines changed

5 files changed

+79
-27
lines changed

benchmark/fs/bench-writeSync.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const fs = require('fs');
5+
const assert = require('assert');
6+
const tmpdir = require('../../test/common/tmpdir');
7+
tmpdir.refresh();
8+
9+
const path = tmpdir.resolve(`new-file-${process.pid}`);
10+
const parameters = [Buffer.from('Benchmark data'),
11+
0,
12+
Buffer.byteLength('Benchmark data')];
13+
const bench = common.createBenchmark(main, {
14+
type: ['valid', 'invalid'],
15+
n: [1e5],
16+
});
17+
18+
function main({ n, type }) {
19+
let fd;
20+
let result;
21+
22+
switch (type) {
23+
case 'valid':
24+
fd = fs.openSync(path, 'w');
25+
26+
bench.start();
27+
for (let i = 0; i < n; i++) {
28+
result = fs.writeSync(fd, ...parameters);
29+
}
30+
31+
bench.end(n);
32+
assert(result);
33+
fs.closeSync(fd);
34+
break;
35+
case 'invalid': {
36+
fd = 1 << 30;
37+
let hasError = false;
38+
bench.start();
39+
for (let i = 0; i < n; i++) {
40+
try {
41+
result = fs.writeSync(fd, ...parameters);
42+
} catch {
43+
hasError = true;
44+
}
45+
}
46+
47+
bench.end(n);
48+
assert(hasError);
49+
break;
50+
}
51+
default:
52+
throw new Error('Invalid type');
53+
}
54+
}

lib/fs.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ const {
107107
getValidatedFd,
108108
getValidatedPath,
109109
getValidMode,
110-
handleErrorFromBinding,
111110
preprocessSymlinkDestination,
112111
Stats,
113112
getStatFsFromBinding,
@@ -897,7 +896,6 @@ ObjectDefineProperty(write, kCustomPromisifyArgsSymbol,
897896
*/
898897
function writeSync(fd, buffer, offsetOrOptions, length, position) {
899898
fd = getValidatedFd(fd);
900-
const ctx = {};
901899
let result;
902900

903901
let offset = offsetOrOptions;
@@ -919,18 +917,15 @@ function writeSync(fd, buffer, offsetOrOptions, length, position) {
919917
if (typeof length !== 'number')
920918
length = buffer.byteLength - offset;
921919
validateOffsetLengthWrite(offset, length, buffer.byteLength);
922-
result = binding.writeBuffer(fd, buffer, offset, length, position,
923-
undefined, ctx);
920+
result = binding.writeBuffer(fd, buffer, offset, length, position);
924921
} else {
925922
validateStringAfterArrayBufferView(buffer, 'buffer');
926923
validateEncoding(buffer, length);
927924

928925
if (offset === undefined)
929926
offset = null;
930-
result = binding.writeString(fd, buffer, offset, length,
931-
undefined, ctx);
927+
result = binding.writeString(fd, buffer, offset, length);
932928
}
933-
handleErrorFromBinding(ctx);
934929
return result;
935930
}
936931

lib/internal/net.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ const {
88

99
const Buffer = require('buffer').Buffer;
1010
const { writeBuffer } = internalBinding('fs');
11-
const errors = require('internal/errors');
1211

1312
// IPv4 Segment
1413
const v4Seg = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])';
@@ -55,12 +54,10 @@ function makeSyncWrite(fd) {
5554

5655
this._handle.bytesWritten += chunk.length;
5756

58-
const ctx = {};
59-
writeBuffer(fd, chunk, 0, chunk.length, null, undefined, ctx);
60-
if (ctx.errno !== undefined) {
61-
const ex = new errors.UVException(ctx);
62-
ex.errno = ctx.errno;
63-
return cb(ex);
57+
try {
58+
writeBuffer(fd, chunk, 0, chunk.length, null);
59+
} catch (e) {
60+
return cb(e);
6461
}
6562
cb();
6663
};

src/node_file.cc

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,7 +2030,7 @@ static void WriteBuffer(const FunctionCallbackInfo<Value>& args) {
20302030
Environment* env = Environment::GetCurrent(args);
20312031

20322032
const int argc = args.Length();
2033-
CHECK_GE(argc, 4);
2033+
CHECK_GE(argc, 5);
20342034

20352035
CHECK(args[0]->IsInt32());
20362036
const int fd = args[0].As<Int32>()->Value();
@@ -2062,13 +2062,16 @@ static void WriteBuffer(const FunctionCallbackInfo<Value>& args) {
20622062
FS_ASYNC_TRACE_BEGIN0(UV_FS_WRITE, req_wrap_async)
20632063
AsyncCall(env, req_wrap_async, args, "write", UTF8, AfterInteger,
20642064
uv_fs_write, fd, &uvbuf, 1, pos);
2065-
} else { // write(fd, buffer, off, len, pos, undefined, ctx)
2066-
CHECK_EQ(argc, 7);
2067-
FSReqWrapSync req_wrap_sync;
2065+
} else { // write(fd, buffer, off, len, pos)
2066+
CHECK_EQ(argc, 5);
2067+
FSReqWrapSync req_wrap_sync("write");
20682068
FS_SYNC_TRACE_BEGIN(write);
2069-
int bytesWritten = SyncCall(env, args[6], &req_wrap_sync, "write",
2070-
uv_fs_write, fd, &uvbuf, 1, pos);
2069+
int bytesWritten = SyncCallAndThrowOnError(
2070+
env, &req_wrap_sync, uv_fs_write, fd, &uvbuf, 1, pos);
20712071
FS_SYNC_TRACE_END(write, "bytesWritten", bytesWritten);
2072+
if (is_uv_error(bytesWritten)) {
2073+
return;
2074+
}
20722075
args.GetReturnValue().Set(bytesWritten);
20732076
}
20742077
}
@@ -2205,9 +2208,9 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
22052208
} else {
22062209
req_wrap_async->SetReturnValue(args);
22072210
}
2208-
} else { // write(fd, string, pos, enc, undefined, ctx)
2209-
CHECK_EQ(argc, 6);
2210-
FSReqWrapSync req_wrap_sync;
2211+
} else { // write(fd, string, pos, enc)
2212+
CHECK_EQ(argc, 4);
2213+
FSReqWrapSync req_wrap_sync("write");
22112214
FSReqBase::FSReqBuffer stack_buffer;
22122215
if (buf == nullptr) {
22132216
if (!StringBytes::StorageSize(isolate, value, enc).To(&len))
@@ -2222,9 +2225,12 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
22222225
}
22232226
uv_buf_t uvbuf = uv_buf_init(buf, len);
22242227
FS_SYNC_TRACE_BEGIN(write);
2225-
int bytesWritten = SyncCall(env, args[5], &req_wrap_sync, "write",
2226-
uv_fs_write, fd, &uvbuf, 1, pos);
2228+
int bytesWritten = SyncCallAndThrowOnError(
2229+
env, &req_wrap_sync, uv_fs_write, fd, &uvbuf, 1, pos);
22272230
FS_SYNC_TRACE_END(write, "bytesWritten", bytesWritten);
2231+
if (is_uv_error(bytesWritten)) {
2232+
return;
2233+
}
22282234
args.GetReturnValue().Set(bytesWritten);
22292235
}
22302236
}

typings/internalBinding/fs.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,15 @@ declare namespace InternalFSBinding {
218218
function utimes(path: string, atime: number, mtime: number, usePromises: typeof kUsePromises): Promise<void>;
219219

220220
function writeBuffer(fd: number, buffer: ArrayBufferView, offset: number, length: number, position: number | null, req: FSReqCallback<number>): void;
221-
function writeBuffer(fd: number, buffer: ArrayBufferView, offset: number, length: number, position: number | null, req: undefined, ctx: FSSyncContext): number;
221+
function writeBuffer(fd: number, buffer: ArrayBufferView, offset: number, length: number, position: number | null): number;
222222
function writeBuffer(fd: number, buffer: ArrayBufferView, offset: number, length: number, position: number | null, usePromises: typeof kUsePromises): Promise<number>;
223223

224224
function writeBuffers(fd: number, buffers: ArrayBufferView[], position: number, req: FSReqCallback<number>): void;
225225
function writeBuffers(fd: number, buffers: ArrayBufferView[], position: number, req: undefined, ctx: FSSyncContext): number;
226226
function writeBuffers(fd: number, buffers: ArrayBufferView[], position: number, usePromises: typeof kUsePromises): Promise<number>;
227227

228228
function writeString(fd: number, value: string, pos: unknown, encoding: unknown, req: FSReqCallback<number>): void;
229-
function writeString(fd: number, value: string, pos: unknown, encoding: unknown, req: undefined, ctx: FSSyncContext): number;
229+
function writeString(fd: number, value: string, pos: unknown, encoding: unknown): number;
230230
function writeString(fd: number, value: string, pos: unknown, encoding: unknown, usePromises: typeof kUsePromises): Promise<number>;
231231

232232
function getFormatOfExtensionlessFile(url: string): ConstantsBinding['fs'];

0 commit comments

Comments
 (0)