@@ -345,44 +345,51 @@ MaybeLocal<Promise> FileHandle::ClosePromise() {
345
345
Isolate* isolate = env ()->isolate ();
346
346
EscapableHandleScope scope (isolate);
347
347
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
+
348
360
auto maybe_resolver = Promise::Resolver::New (context);
349
361
CHECK (!maybe_resolver.IsEmpty ());
350
362
Local<Promise::Resolver> resolver = maybe_resolver.ToLocalChecked ();
351
363
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 ();
380
385
}
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;
385
391
}
392
+
386
393
return scope.Escape (promise);
387
394
}
388
395
@@ -2538,7 +2545,7 @@ void Initialize(Local<Object> target,
2538
2545
env->SetProtoMethod (fd, " close" , FileHandle::Close);
2539
2546
env->SetProtoMethod (fd, " releaseFD" , FileHandle::ReleaseFD);
2540
2547
Local<ObjectTemplate> fdt = fd->InstanceTemplate ();
2541
- fdt->SetInternalFieldCount (StreamBase ::kInternalFieldCount );
2548
+ fdt->SetInternalFieldCount (FileHandle ::kInternalFieldCount );
2542
2549
StreamBase::AddMethods (env, fd);
2543
2550
env->SetConstructorFunction (target, " FileHandle" , fd);
2544
2551
env->set_fd_constructor_template (fdt);
0 commit comments