Skip to content

Commit 769e7d4

Browse files
committed
fs: improve error performance of readdirSync
1 parent ceedb3a commit 769e7d4

File tree

4 files changed

+25
-33
lines changed

4 files changed

+25
-33
lines changed

lib/fs.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -1417,17 +1417,16 @@ function readdirSyncRecursive(basePath, options) {
14171417
const readdirResults = [];
14181418
const pathsQueue = [basePath];
14191419

1420-
const ctx = { path: basePath };
14211420
function read(path) {
1422-
ctx.path = path;
14231421
const readdirResult = binding.readdir(
14241422
pathModule.toNamespacedPath(path),
14251423
encoding,
14261424
withFileTypes,
1427-
undefined,
1428-
ctx,
14291425
);
1430-
handleErrorFromBinding(ctx);
1426+
1427+
if (readdirResult === undefined) {
1428+
return;
1429+
}
14311430

14321431
if (withFileTypes) {
14331432
// Calling `readdir` with `withFileTypes=true`, the result is an array of arrays.
@@ -1526,12 +1525,13 @@ function readdirSync(path, options) {
15261525
return readdirSyncRecursive(path, options);
15271526
}
15281527

1529-
const ctx = { path };
1530-
const result = binding.readdir(pathModule.toNamespacedPath(path),
1531-
options.encoding, !!options.withFileTypes,
1532-
undefined, ctx);
1533-
handleErrorFromBinding(ctx);
1534-
return options.withFileTypes ? getDirents(path, result) : result;
1528+
const result = binding.readdir(
1529+
pathModule.toNamespacedPath(path),
1530+
options.encoding,
1531+
!!options.withFileTypes,
1532+
);
1533+
1534+
return result !== undefined && options.withFileTypes ? getDirents(path, result) : result;
15351535
}
15361536

15371537
/**

src/node_file.cc

+10-18
Original file line numberDiff line numberDiff line change
@@ -1893,8 +1893,8 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
18931893

18941894
bool with_types = args[2]->IsTrue();
18951895

1896-
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
1897-
if (req_wrap_async != nullptr) { // readdir(path, encoding, withTypes, req)
1896+
if (argc > 3) { // readdir(path, encoding, withTypes, req)
1897+
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
18981898
req_wrap_async->set_with_file_types(with_types);
18991899
FS_ASYNC_TRACE_BEGIN1(
19001900
UV_FS_SCANDIR, req_wrap_async, "path", TRACE_STR_COPY(*path))
@@ -1907,18 +1907,15 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
19071907
uv_fs_scandir,
19081908
*path,
19091909
0 /*flags*/);
1910-
} else { // readdir(path, encoding, withTypes, undefined, ctx)
1911-
CHECK_EQ(argc, 5);
1912-
FSReqWrapSync req_wrap_sync;
1910+
} else { // readdir(path, encoding, withTypes)
1911+
FSReqWrapSync req_wrap_sync("scandir", *path);
19131912
FS_SYNC_TRACE_BEGIN(readdir);
1914-
int err = SyncCall(env, args[4], &req_wrap_sync, "scandir",
1915-
uv_fs_scandir, *path, 0 /*flags*/);
1913+
int err = SyncCallAndThrowOnError(env, &req_wrap_sync, uv_fs_scandir, *path, 0 /*flags*/);
19161914
FS_SYNC_TRACE_END(readdir);
1917-
if (err < 0) {
1918-
return; // syscall failed, no need to continue, error info is in ctx
1915+
if (is_uv_error(err)) {
1916+
return;
19191917
}
19201918

1921-
CHECK_GE(req_wrap_sync.req.result, 0);
19221919
int r;
19231920
std::vector<Local<Value>> name_v;
19241921
std::vector<Local<Value>> type_v;
@@ -1929,12 +1926,8 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
19291926
r = uv_fs_scandir_next(&(req_wrap_sync.req), &ent);
19301927
if (r == UV_EOF)
19311928
break;
1932-
if (r != 0) {
1933-
Local<Object> ctx = args[4].As<Object>();
1934-
ctx->Set(env->context(), env->errno_string(),
1935-
Integer::New(isolate, r)).Check();
1936-
ctx->Set(env->context(), env->syscall_string(),
1937-
OneByteString(isolate, "readdir")).Check();
1929+
if (is_uv_error(r)) {
1930+
env->ThrowUVException(r);
19381931
return;
19391932
}
19401933

@@ -1945,8 +1938,7 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
19451938
&error);
19461939

19471940
if (filename.IsEmpty()) {
1948-
Local<Object> ctx = args[4].As<Object>();
1949-
ctx->Set(env->context(), env->error_string(), error).Check();
1941+
isolate->ThrowException(error);
19501942
return;
19511943
}
19521944

test/parallel/test-fs-readdir-types.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ tmpdir.refresh();
2929

3030
// Create the necessary files
3131
files.forEach(function(currentFile) {
32-
fs.closeSync(fs.openSync(`${readdirDir}/${currentFile}`, 'w'));
32+
fs.writeFileSync(`${readdirDir}/${currentFile}`, '', 'utf8');
3333
});
3434

3535

@@ -95,7 +95,7 @@ binding.readdir = common.mustCall((path, encoding, types, req, ctx) => {
9595
};
9696
oldReaddir(path, encoding, types, req);
9797
} else {
98-
const results = oldReaddir(path, encoding, types, req, ctx);
98+
const results = oldReaddir(path, encoding, types);
9999
results[1] = results[1].map(() => UNKNOWN);
100100
return results;
101101
}

typings/internalBinding/fs.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ declare namespace InternalFSBinding {
166166
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: true, req: FSReqCallback<[string[], number[]]>): void;
167167
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: false, req: FSReqCallback<string[]>): void;
168168
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: boolean, req: undefined, ctx: FSSyncContext): string[] | [string[], number[]];
169-
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: true, req: undefined, ctx: FSSyncContext): [string[], number[]];
170-
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: false, req: undefined, ctx: FSSyncContext): string[];
169+
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: true): [string[], number[]];
170+
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: false): string[];
171171
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: boolean, usePromises: typeof kUsePromises): Promise<string[] | [string[], number[]]>;
172172
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: true, usePromises: typeof kUsePromises): Promise<[string[], number[]]>;
173173
function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: false, usePromises: typeof kUsePromises): Promise<string[]>;

0 commit comments

Comments
 (0)