Skip to content

Commit 8368555

Browse files
anonrigaduh95
authored andcommitted
fs: add v8 fast api to closeSync
PR-URL: #53627 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br> Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 3a0fcbb commit 8368555

File tree

4 files changed

+49
-7
lines changed

4 files changed

+49
-7
lines changed

src/env.cc

+14-3
Original file line numberDiff line numberDiff line change
@@ -1841,12 +1841,23 @@ void Environment::AddUnmanagedFd(int fd) {
18411841
}
18421842
}
18431843

1844-
void Environment::RemoveUnmanagedFd(int fd) {
1844+
void Environment::RemoveUnmanagedFd(int fd, bool schedule_native_immediate) {
18451845
if (!tracks_unmanaged_fds()) return;
18461846
size_t removed_count = unmanaged_fds_.erase(fd);
18471847
if (removed_count == 0) {
1848-
ProcessEmitWarning(
1849-
this, "File descriptor %d closed but not opened in unmanaged mode", fd);
1848+
if (schedule_native_immediate) {
1849+
SetImmediateThreadsafe([&](Environment* env) {
1850+
ProcessEmitWarning(this,
1851+
"File descriptor %d closed but not opened in "
1852+
"unmanaged mode",
1853+
fd);
1854+
});
1855+
} else {
1856+
ProcessEmitWarning(
1857+
this,
1858+
"File descriptor %d closed but not opened in unmanaged mode",
1859+
fd);
1860+
}
18501861
}
18511862
}
18521863

src/env.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,7 @@ class Environment : public MemoryRetainer {
10271027
std::unique_ptr<v8::BackingStore> release_managed_buffer(const uv_buf_t& buf);
10281028

10291029
void AddUnmanagedFd(int fd);
1030-
void RemoveUnmanagedFd(int fd);
1030+
void RemoveUnmanagedFd(int fd, bool schedule_native_immediate = false);
10311031

10321032
template <typename T>
10331033
void ForEachRealm(T&& iterator) const;

src/node_external_reference.h

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ using CFunctionCallbackWithUint8ArrayUint32Int64Bool =
4747
uint32_t,
4848
int64_t,
4949
bool);
50+
using CFunctionWithObjectInt32Fallback = void (*)(v8::Local<v8::Object>,
51+
int32_t input,
52+
v8::FastApiCallbackOptions&);
5053
using CFunctionWithUint32 = uint32_t (*)(v8::Local<v8::Value>,
5154
const uint32_t input);
5255
using CFunctionWithDoubleReturnDouble = double (*)(v8::Local<v8::Value>,
@@ -75,6 +78,7 @@ class ExternalReferenceRegistry {
7578
V(CFunctionCallbackWithTwoUint8Arrays) \
7679
V(CFunctionCallbackWithTwoUint8ArraysFallback) \
7780
V(CFunctionCallbackWithUint8ArrayUint32Int64Bool) \
81+
V(CFunctionWithObjectInt32Fallback) \
7882
V(CFunctionWithUint32) \
7983
V(CFunctionWithDoubleReturnDouble) \
8084
V(CFunctionWithInt64Fallback) \

src/node_file.cc

+30-3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ namespace fs {
5454

5555
using v8::Array;
5656
using v8::BigInt;
57+
using v8::CFunction;
5758
using v8::Context;
5859
using v8::EscapableHandleScope;
5960
using v8::FastApiCallbackOptions;
@@ -298,7 +299,7 @@ FileHandle::TransferData::~TransferData() {
298299

299300
BaseObjectPtr<BaseObject> FileHandle::TransferData::Deserialize(
300301
Environment* env,
301-
v8::Local<v8::Context> context,
302+
Local<v8::Context> context,
302303
std::unique_ptr<worker::TransferData> self) {
303304
BindingData* bd = Realm::GetBindingData<BindingData>(context);
304305
if (bd == nullptr) return {};
@@ -960,7 +961,7 @@ void Access(const FunctionCallbackInfo<Value>& args) {
960961
}
961962
}
962963

963-
void Close(const FunctionCallbackInfo<Value>& args) {
964+
static void Close(const FunctionCallbackInfo<Value>& args) {
964965
Environment* env = Environment::GetCurrent(args);
965966

966967
const int argc = args.Length();
@@ -986,6 +987,30 @@ void Close(const FunctionCallbackInfo<Value>& args) {
986987
}
987988
}
988989

990+
static void FastClose(Local<Object> recv,
991+
int32_t fd,
992+
// NOLINTNEXTLINE(runtime/references) This is V8 api.
993+
v8::FastApiCallbackOptions& options) {
994+
Environment* env = Environment::GetCurrent(recv->GetCreationContextChecked());
995+
996+
uv_fs_t req;
997+
FS_SYNC_TRACE_BEGIN(close);
998+
int err = uv_fs_close(nullptr, &req, fd, nullptr) < 0;
999+
FS_SYNC_TRACE_END(close);
1000+
uv_fs_req_cleanup(&req);
1001+
1002+
if (err < 0) {
1003+
options.fallback = true;
1004+
} else {
1005+
// Note: Only remove unmanaged fds if the close was successful.
1006+
// RemoveUnmanagedFd() can call ProcessEmitWarning() which calls back into
1007+
// JS process.emitWarning() and violates the fast API protocol.
1008+
env->RemoveUnmanagedFd(fd, true /* schedule native immediate */);
1009+
}
1010+
}
1011+
1012+
CFunction fast_close_ = CFunction::Make(FastClose);
1013+
9891014
static void ExistsSync(const FunctionCallbackInfo<Value>& args) {
9901015
Environment* env = Environment::GetCurrent(args);
9911016
Isolate* isolate = env->isolate();
@@ -3305,7 +3330,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
33053330
"getFormatOfExtensionlessFile",
33063331
GetFormatOfExtensionlessFile);
33073332
SetMethod(isolate, target, "access", Access);
3308-
SetMethod(isolate, target, "close", Close);
3333+
SetFastMethod(isolate, target, "close", Close, &fast_close_);
33093334
SetMethod(isolate, target, "existsSync", ExistsSync);
33103335
SetMethod(isolate, target, "open", Open);
33113336
SetMethod(isolate, target, "openFileHandle", OpenFileHandle);
@@ -3430,6 +3455,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
34303455

34313456
registry->Register(GetFormatOfExtensionlessFile);
34323457
registry->Register(Close);
3458+
registry->Register(FastClose);
3459+
registry->Register(fast_close_.GetTypeInfo());
34333460
registry->Register(ExistsSync);
34343461
registry->Register(Open);
34353462
registry->Register(OpenFileHandle);

0 commit comments

Comments
 (0)