mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
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: https://github.com/nodejs/node/pull/39472 Refs: https://github.com/nodejs/node/issues/39464 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
This commit is contained in:
1 parent
71b2df253d
commit
f1d353398e
1 file changed
+9
-1
+9
-1
@@ -215,6 +215,7 @@ FileHandle::TransferData::TransferData(int fd) : fd_(fd) {}
|
||||
FileHandle::TransferData::~TransferData() {
|
||||
if (fd_ > 0) {
|
||||
uv_fs_t close_req;
|
||||
CHECK_NE(fd_, -1);
|
||||
CHECK_EQ(0, uv_fs_close(nullptr, &close_req, fd_, nullptr));
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
}
|
||||
@@ -237,8 +238,9 @@ BaseObjectPtr<BaseObject> FileHandle::TransferData::Deserialize(
|
||||
// JS during GC. If closing the fd fails at this point, a fatal exception
|
||||
// will crash the process immediately.
|
||||
inline void FileHandle::Close() {
|
||||
if (closed_) return;
|
||||
if (closed_ || closing_) return;
|
||||
uv_fs_t req;
|
||||
CHECK_NE(fd_, -1);
|
||||
int ret = uv_fs_close(env()->event_loop(), &req, fd_, nullptr);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
@@ -384,6 +386,7 @@ MaybeLocal<Promise> FileHandle::ClosePromise() {
|
||||
close->Resolve();
|
||||
}
|
||||
}};
|
||||
CHECK_NE(fd_, -1);
|
||||
int ret = req->Dispatch(uv_fs_close, fd_, AfterClose);
|
||||
if (ret < 0) {
|
||||
req->Reject(UVException(isolate, ret, "close"));
|
||||
@@ -555,8 +558,13 @@ ShutdownWrap* FileHandle::CreateShutdownWrap(Local<Object> object) {
|
||||
}
|
||||
|
||||
int FileHandle::DoShutdown(ShutdownWrap* req_wrap) {
|
||||
if (closing_ || closed_) {
|
||||
req_wrap->Done(0);
|
||||
return 1;
|
||||
}
|
||||
FileHandleCloseWrap* wrap = static_cast<FileHandleCloseWrap*>(req_wrap);
|
||||
closing_ = true;
|
||||
CHECK_NE(fd_, -1);
|
||||
wrap->Dispatch(uv_fs_close, fd_, uv_fs_callback_t{[](uv_fs_t* req) {
|
||||
FileHandleCloseWrap* wrap = static_cast<FileHandleCloseWrap*>(
|
||||
FileHandleCloseWrap::from_req(req));
|
||||
|
||||
Reference in new issue
Block a user