Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The Closer and Remover finalizers are defined on different objects in Tempfile. The Closer is defined on the Tempfile object while the Remover is defined on the finalizer_obj. This means that there is no guarantee of the finalizer order. On Windows, we must close the file before removing it because we cannot remove an open file. But since the order is not guaranteed, the GC may run the Remover finalizer first, which will fail with an Errno::EACCES (Permission denied @ apply2files). This commit changes it so that both the Closer and Remover finalizers are defined on the finalizer_obj, which guarantees the order that it is ran.
- Loading branch information
eb2d8b1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I can see the issue on Windows, I don't think this change is correct. Each
Tempfile
instance has a separate File instance and file descriptor:I think you still need the finalizers defined in
initialize_dup
andinitialize_clone
, even if they use@finalizer_obj
instead ofself
. TheObjectSpace.undefine_finalizer(@finalizer_obj)
inopen
looks wrong as it will undefine the closer finalizers for other related Tempfile instances that were created bydup
/clone
.Even if you do this, it means that if you are using
dup
/clone
, the tempfile fds will not be closed until all related Tempfile instances are GCed.