Skip to content

Commit 1055136

Browse files
author
pluris
committed
fs: improve error performance for writeSync
1 parent 6a1abd2 commit 1055136

File tree

3 files changed

+73
-20
lines changed

3 files changed

+73
-20
lines changed

benchmark/fs/bench-writeSync.js

+54
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

+2-7
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ const {
107107
getValidatedFd,
108108
getValidatedPath,
109109
getValidMode,
110-
handleErrorFromBinding,
111110
possiblyTransformPath,
112111
preprocessSymlinkDestination,
113112
Stats,
@@ -898,7 +897,6 @@ ObjectDefineProperty(write, kCustomPromisifyArgsSymbol,
898897
*/
899898
function writeSync(fd, buffer, offsetOrOptions, length, position) {
900899
fd = getValidatedFd(fd);
901-
const ctx = {};
902900
let result;
903901

904902
let offset = offsetOrOptions;
@@ -920,18 +918,15 @@ function writeSync(fd, buffer, offsetOrOptions, length, position) {
920918
if (typeof length !== 'number')
921919
length = buffer.byteLength - offset;
922920
validateOffsetLengthWrite(offset, length, buffer.byteLength);
923-
result = binding.writeBuffer(fd, buffer, offset, length, position,
924-
undefined, ctx);
921+
result = binding.writeBuffer(fd, buffer, offset, length, position);
925922
} else {
926923
validateStringAfterArrayBufferView(buffer, 'buffer');
927924
validateEncoding(buffer, length);
928925

929926
if (offset === undefined)
930927
offset = null;
931-
result = binding.writeString(fd, buffer, offset, length,
932-
undefined, ctx);
928+
result = binding.writeString(fd, buffer, offset, length);
933929
}
934-
handleErrorFromBinding(ctx);
935930
return result;
936931
}
937932

src/node_file.cc

+17-13
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();
@@ -2057,18 +2057,20 @@ static void WriteBuffer(const FunctionCallbackInfo<Value>& args) {
20572057
char* buf = buffer_data + off;
20582058
uv_buf_t uvbuf = uv_buf_init(buf, len);
20592059

2060-
FSReqBase* req_wrap_async = GetReqWrap(args, 5);
2061-
if (req_wrap_async != nullptr) { // write(fd, buffer, off, len, pos, req)
2060+
if (argc == 6) { // write(fd, buffer, off, len, pos, req)
2061+
FSReqBase* req_wrap_async = GetReqWrap(args, 5);
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+
FSReqWrapSync req_wrap_sync("write");
20682067
FS_SYNC_TRACE_BEGIN(write);
2069-
int bytesWritten = SyncCall(env, args[6], &req_wrap_sync, "write",
2070-
uv_fs_write, fd, &uvbuf, 1, pos);
2068+
int bytesWritten = SyncCallAndThrowOnError(
2069+
env, &req_wrap_sync, uv_fs_write, fd, &uvbuf, 1, pos);
20712070
FS_SYNC_TRACE_END(write, "bytesWritten", bytesWritten);
2071+
if (is_uv_error(bytesWritten)) {
2072+
return;
2073+
}
20722074
args.GetReturnValue().Set(bytesWritten);
20732075
}
20742076
}
@@ -2205,9 +2207,8 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
22052207
} else {
22062208
req_wrap_async->SetReturnValue(args);
22072209
}
2208-
} else { // write(fd, string, pos, enc, undefined, ctx)
2209-
CHECK_EQ(argc, 6);
2210-
FSReqWrapSync req_wrap_sync;
2210+
} else { // write(fd, string, pos, enc)
2211+
FSReqWrapSync req_wrap_sync("write");
22112212
FSReqBase::FSReqBuffer stack_buffer;
22122213
if (buf == nullptr) {
22132214
if (!StringBytes::StorageSize(isolate, value, enc).To(&len))
@@ -2222,9 +2223,12 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
22222223
}
22232224
uv_buf_t uvbuf = uv_buf_init(buf, len);
22242225
FS_SYNC_TRACE_BEGIN(write);
2225-
int bytesWritten = SyncCall(env, args[5], &req_wrap_sync, "write",
2226-
uv_fs_write, fd, &uvbuf, 1, pos);
2226+
int bytesWritten = SyncCallAndThrowOnError(
2227+
env, &req_wrap_sync, uv_fs_write, fd, &uvbuf, 1, pos);
22272228
FS_SYNC_TRACE_END(write, "bytesWritten", bytesWritten);
2229+
if (is_uv_error(bytesWritten)) {
2230+
return;
2231+
}
22282232
args.GetReturnValue().Set(bytesWritten);
22292233
}
22302234
}

0 commit comments

Comments
 (0)