@@ -345,44 +345,51 @@ MaybeLocal<Promise> FileHandle::ClosePromise() {
345345 Isolate* isolate = env ()->isolate ();
346346 EscapableHandleScope scope (isolate);
347347 Local<Context> context = env ()->context ();
348+
349+ Local<Value> close_resolver =
350+ object ()->GetInternalField (FileHandle::kClosingPromiseSlot );
351+ if (!close_resolver.IsEmpty () && !close_resolver->IsUndefined ()) {
352+ CHECK (close_resolver->IsPromise ());
353+ return close_resolver.As <Promise>();
354+ }
355+
356+ CHECK (!closed_);
357+ CHECK (!closing_);
358+ CHECK (!reading_);
359+
348360 auto maybe_resolver = Promise::Resolver::New (context);
349361 CHECK (!maybe_resolver.IsEmpty ());
350362 Local<Promise::Resolver> resolver = maybe_resolver.ToLocalChecked ();
351363 Local<Promise> promise = resolver.As <Promise>();
352- CHECK (!reading_);
353- if (!closed_ && !closing_) {
354- closing_ = true ;
355- Local<Object> close_req_obj;
356- if (!env ()
357- ->fdclose_constructor_template ()
358- ->NewInstance (env ()->context ())
359- .ToLocal (&close_req_obj)) {
360- return MaybeLocal<Promise>();
361- }
362- CloseReq* req = new CloseReq (env (), close_req_obj, promise, object ());
363- auto AfterClose = uv_fs_callback_t {[](uv_fs_t * req) {
364- std::unique_ptr<CloseReq> close (CloseReq::from_req (req));
365- CHECK_NOT_NULL (close);
366- close->file_handle ()->AfterClose ();
367- Isolate* isolate = close->env ()->isolate ();
368- if (req->result < 0 ) {
369- HandleScope handle_scope (isolate);
370- close->Reject (
371- UVException (isolate, static_cast <int >(req->result ), " close" ));
372- } else {
373- close->Resolve ();
374- }
375- }};
376- int ret = req->Dispatch (uv_fs_close, fd_, AfterClose);
377- if (ret < 0 ) {
378- req->Reject (UVException (isolate, ret, " close" ));
379- delete req;
364+
365+ Local<Object> close_req_obj;
366+ if (!env ()->fdclose_constructor_template ()
367+ ->NewInstance (env ()->context ()).ToLocal (&close_req_obj)) {
368+ return MaybeLocal<Promise>();
369+ }
370+ closing_ = true ;
371+ object ()->SetInternalField (FileHandle::kClosingPromiseSlot , promise);
372+
373+ CloseReq* req = new CloseReq (env (), close_req_obj, promise, object ());
374+ auto AfterClose = uv_fs_callback_t {[](uv_fs_t * req) {
375+ std::unique_ptr<CloseReq> close (CloseReq::from_req (req));
376+ CHECK_NOT_NULL (close);
377+ close->file_handle ()->AfterClose ();
378+ Isolate* isolate = close->env ()->isolate ();
379+ if (req->result < 0 ) {
380+ HandleScope handle_scope (isolate);
381+ close->Reject (
382+ UVException (isolate, static_cast <int >(req->result ), " close" ));
383+ } else {
384+ close->Resolve ();
380385 }
381- } else {
382- // Already closed. Just reject the promise immediately
383- resolver->Reject (context, UVException (isolate, UV_EBADF, " close" ))
384- .Check ();
386+ }};
387+ int ret = req->Dispatch (uv_fs_close, fd_, AfterClose);
388+ if (ret < 0 ) {
389+ req->Reject (UVException (isolate, ret, " close" ));
390+ delete req;
385391 }
392+
386393 return scope.Escape (promise);
387394}
388395
@@ -2538,7 +2545,7 @@ void Initialize(Local<Object> target,
25382545 env->SetProtoMethod (fd, " close" , FileHandle::Close);
25392546 env->SetProtoMethod (fd, " releaseFD" , FileHandle::ReleaseFD);
25402547 Local<ObjectTemplate> fdt = fd->InstanceTemplate ();
2541- fdt->SetInternalFieldCount (StreamBase ::kInternalFieldCount );
2548+ fdt->SetInternalFieldCount (FileHandle ::kInternalFieldCount );
25422549 StreamBase::AddMethods (env, fd);
25432550 env->SetConstructorFunction (target, " FileHandle" , fd);
25442551 env->set_fd_constructor_template (fdt);
0 commit comments