@@ -54,6 +54,7 @@ namespace fs {
5454
5555using v8::Array;
5656using v8::BigInt;
57+ using v8::CFunction;
5758using v8::Context;
5859using v8::EscapableHandleScope;
5960using v8::FastApiCallbackOptions;
@@ -298,7 +299,7 @@ FileHandle::TransferData::~TransferData() {
298299
299300BaseObjectPtr<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+
9891014static 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