You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Change delayed delete mechanism to prevent cross-drive mv failure for in-use DLL (#59635)
On Windows, during precompilation of package `A`, a DLL file is
generated and may replace the existing one. If `A` is already loaded in
the julia session however, the corresponding soon-to-be-obsolete DLL
cannot be removed while julia is running. Currently, this problem is
solved by moving the old DLL in a special "julia_delayed_deletes"
folder, which will be cleaned in a later julia session by `Pkg.gc()`.
However, moving an in-use DLL is only permitted on the same drive, and
the "julia_delayed_deletes" is located in the `tempdir`, a.k.a. on a
fixed drive, say `C:`. Thus, if the `DEPOT_PATH` points to a ".julia" in
another drive, say `D:`, any precompilation occuring on an already
loaded package will fail. This is what happens in #59589, actually
resulting in an infinite loop that bloats up both memory and disk.
@staticfloat had actually predicted that such an issue could occur in
#53456 (comment).
This PR fixes#59589 by changing the "delayed deleting" mechanism:
instead of moving the old DLLs to a fixed folder, they are renamed in
their initial folder and recorded in a list stored at a fixed location.
Upon `Pkg.gc()`, the listed obsolete files will be deleted
(JuliaLang/Pkg.jl#4392).
It also prevents any similar infinite loops by cutting the `rm -> mv ->
rm` cycle into `rm -> rename`. ~I also removed the private argument
`allow_delayed_delete` from `rm`, which is only called in by
[Pkg](https://github.com/JuliaLang/Pkg.jl/blob/7344e2656475261a83a6bd37d9d4cc1e7dcf5f0d/src/API.jl#L1127)
but does not appear to be useful.~
EDIT: current state is
#59635 (comment)
---------
Co-authored-by: Jameson Nash <[email protected]>
Co-authored-by: Elliot Saba <[email protected]>
# deprecated internal function used by some packages
679
689
temp_cleanup_purge(; force=false) = force ?temp_cleanup_purge_all() :@lock TEMP_CLEANUP_LOCK temp_cleanup_purge_prelocked(false)
680
690
691
+
functiontemp_cleanup_postprocess(cleanup_dirs)
692
+
if!isempty(cleanup_dirs)
693
+
rmcmd ="""
694
+
cleanuplist = readlines(stdin) # This loop won't start running until stdin is closed, which is supposed to be sequenced after the process exits
695
+
sleep(1) # Wait for the operating system to hopefully be ready, since the OS implementation is probably incorrect, given the history of buggy work-arounds like this that have existed for ages in dotNet and libuv
696
+
for path in cleanuplist
697
+
try
698
+
rm(path, force=true, recursive=true)
699
+
catch ex
700
+
@warn "Failed to clean up temporary path \$(repr(path))\n\$ex" _group=:file
0 commit comments