@@ -54,6 +54,7 @@ namespace fs {
54
54
55
55
using v8::Array;
56
56
using v8::BigInt;
57
+ using v8::CFunction;
57
58
using v8::Context;
58
59
using v8::EscapableHandleScope;
59
60
using v8::FastApiCallbackOptions;
@@ -298,7 +299,7 @@ FileHandle::TransferData::~TransferData() {
298
299
299
300
BaseObjectPtr<BaseObject> FileHandle::TransferData::Deserialize (
300
301
Environment* env,
301
- v8:: Local<v8::Context> context,
302
+ Local<v8::Context> context,
302
303
std::unique_ptr<worker::TransferData> self) {
303
304
BindingData* bd = Realm::GetBindingData<BindingData>(context);
304
305
if (bd == nullptr ) return {};
@@ -960,7 +961,7 @@ void Access(const FunctionCallbackInfo<Value>& args) {
960
961
}
961
962
}
962
963
963
- void Close (const FunctionCallbackInfo<Value>& args) {
964
+ static void Close (const FunctionCallbackInfo<Value>& args) {
964
965
Environment* env = Environment::GetCurrent (args);
965
966
966
967
const int argc = args.Length ();
@@ -986,6 +987,30 @@ void Close(const FunctionCallbackInfo<Value>& args) {
986
987
}
987
988
}
988
989
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
+
989
1014
static void ExistsSync (const FunctionCallbackInfo<Value>& args) {
990
1015
Environment* env = Environment::GetCurrent (args);
991
1016
Isolate* isolate = env->isolate ();
@@ -3305,7 +3330,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
3305
3330
" getFormatOfExtensionlessFile" ,
3306
3331
GetFormatOfExtensionlessFile);
3307
3332
SetMethod (isolate, target, " access" , Access);
3308
- SetMethod (isolate, target, " close" , Close);
3333
+ SetFastMethod (isolate, target, " close" , Close, &fast_close_ );
3309
3334
SetMethod (isolate, target, " existsSync" , ExistsSync);
3310
3335
SetMethod (isolate, target, " open" , Open);
3311
3336
SetMethod (isolate, target, " openFileHandle" , OpenFileHandle);
@@ -3430,6 +3455,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
3430
3455
3431
3456
registry->Register (GetFormatOfExtensionlessFile);
3432
3457
registry->Register (Close);
3458
+ registry->Register (FastClose);
3459
+ registry->Register (fast_close_.GetTypeInfo ());
3433
3460
registry->Register (ExistsSync);
3434
3461
registry->Register (Open);
3435
3462
registry->Register (OpenFileHandle);
0 commit comments