Skip to content

Commit 72ad6d3

Browse files
jasnellBethGriggs
authored andcommitted
fs: check closing_ in FileHandle::Close
Fix possible flaky failure. Keep uv_fs_close from being called twice on the same fd. Signed-off-by: James M Snell <jasnell@gmail.com> PR-URL: #39472 Refs: #39464 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent e552b1a commit 72ad6d3

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

src/node_file.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ FileHandle::TransferData::TransferData(int fd) : fd_(fd) {}
215215
FileHandle::TransferData::~TransferData() {
216216
if (fd_ > 0) {
217217
uv_fs_t close_req;
218+
CHECK_NE(fd_, -1);
218219
CHECK_EQ(0, uv_fs_close(nullptr, &close_req, fd_, nullptr));
219220
uv_fs_req_cleanup(&close_req);
220221
}
@@ -237,8 +238,9 @@ BaseObjectPtr<BaseObject> FileHandle::TransferData::Deserialize(
237238
// JS during GC. If closing the fd fails at this point, a fatal exception
238239
// will crash the process immediately.
239240
inline void FileHandle::Close() {
240-
if (closed_) return;
241+
if (closed_ || closing_) return;
241242
uv_fs_t req;
243+
CHECK_NE(fd_, -1);
242244
int ret = uv_fs_close(env()->event_loop(), &req, fd_, nullptr);
243245
uv_fs_req_cleanup(&req);
244246

@@ -384,6 +386,7 @@ MaybeLocal<Promise> FileHandle::ClosePromise() {
384386
close->Resolve();
385387
}
386388
}};
389+
CHECK_NE(fd_, -1);
387390
int ret = req->Dispatch(uv_fs_close, fd_, AfterClose);
388391
if (ret < 0) {
389392
req->Reject(UVException(isolate, ret, "close"));
@@ -555,8 +558,13 @@ ShutdownWrap* FileHandle::CreateShutdownWrap(Local<Object> object) {
555558
}
556559

557560
int FileHandle::DoShutdown(ShutdownWrap* req_wrap) {
561+
if (closing_ || closed_) {
562+
req_wrap->Done(0);
563+
return 1;
564+
}
558565
FileHandleCloseWrap* wrap = static_cast<FileHandleCloseWrap*>(req_wrap);
559566
closing_ = true;
567+
CHECK_NE(fd_, -1);
560568
wrap->Dispatch(uv_fs_close, fd_, uv_fs_callback_t{[](uv_fs_t* req) {
561569
FileHandleCloseWrap* wrap = static_cast<FileHandleCloseWrap*>(
562570
FileHandleCloseWrap::from_req(req));

0 commit comments

Comments
 (0)