@@ -345,44 +345,48 @@ MaybeLocal<Promise> FileHandle::ClosePromise() {
345345 Isolate* isolate = env ()->isolate ();
346346 EscapableHandleScope scope (isolate);
347347 Local<Context> context = env ()->context ();
348+
349+ Local<Promise::Resolver> close_resolver = close_promise_.Get (isolate);
350+ if (!close_resolver.IsEmpty ())
351+ return close_resolver.As <Promise>();
352+
353+ CHECK (!closed_);
354+ CHECK (!closing_);
355+ CHECK (!reading_);
356+
348357 auto maybe_resolver = Promise::Resolver::New (context);
349358 CHECK (!maybe_resolver.IsEmpty ());
350359 Local<Promise::Resolver> resolver = maybe_resolver.ToLocalChecked ();
351360 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;
361+
362+ Local<Object> close_req_obj;
363+ if (!env ()->fdclose_constructor_template ()
364+ ->NewInstance (env ()->context ()).ToLocal (&close_req_obj)) {
365+ return MaybeLocal<Promise>();
366+ }
367+ closing_ = true ;
368+ close_promise_.Reset (isolate, resolver);
369+
370+ CloseReq* req = new CloseReq (env (), close_req_obj, promise, object ());
371+ auto AfterClose = uv_fs_callback_t {[](uv_fs_t * req) {
372+ std::unique_ptr<CloseReq> close (CloseReq::from_req (req));
373+ CHECK_NOT_NULL (close);
374+ close->file_handle ()->AfterClose ();
375+ Isolate* isolate = close->env ()->isolate ();
376+ if (req->result < 0 ) {
377+ HandleScope handle_scope (isolate);
378+ close->Reject (
379+ UVException (isolate, static_cast <int >(req->result ), " close" ));
380+ } else {
381+ close->Resolve ();
380382 }
381- } else {
382- // Already closed. Just reject the promise immediately
383- resolver->Reject (context, UVException (isolate, UV_EBADF, " close" ))
384- .Check ();
383+ }};
384+ int ret = req->Dispatch (uv_fs_close, fd_, AfterClose);
385+ if (ret < 0 ) {
386+ req->Reject (UVException (isolate, ret, " close" ));
387+ delete req;
385388 }
389+
386390 return scope.Escape (promise);
387391}
388392
0 commit comments