Skip to content

Commit c79f4b8

Browse files
rework ocachefile name uniquing
1 parent 31ef088 commit c79f4b8

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

base/loading.jl

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2902,27 +2902,7 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in
29022902
end
29032903

29042904
if cache_objects
2905-
try
2906-
rename(tmppath_so, ocachefile::String; force=true)
2907-
catch e
2908-
e isa IOError || rethrow()
2909-
isfile(ocachefile::String) || rethrow()
2910-
# Windows prevents renaming a file that is in use so if there is a Julia session started
2911-
# with a package image loaded, we cannot rename that file.
2912-
# The code belows append a `_i` to the name of the cache file where `i` is the smallest number such that
2913-
# that cache file does not exist.
2914-
ocachename, ocacheext = splitext(ocachefile::String)
2915-
old_cachefiles = Set(readdir(cachepath))
2916-
num = 1
2917-
while true
2918-
ocachefile = ocachename * "_$num" * ocacheext
2919-
in(basename(ocachefile), old_cachefiles) || break
2920-
num += 1
2921-
end
2922-
# TODO: Risk for a race here if some other process grabs this name before us
2923-
cachefile = cachefile_from_ocachefile(ocachefile)
2924-
rename(tmppath_so, ocachefile::String; force=true)
2925-
end
2905+
ocachefile = rename_unique_ocachefile(tmppath_so, ocachefile)
29262906
@static if Sys.isapple()
29272907
run(`$(Linking.dsymutil()) $ocachefile`, Base.DevNull(), Base.DevNull(), Base.DevNull())
29282908
end
@@ -2945,6 +2925,27 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in
29452925
end
29462926
end
29472927

2928+
function rename_unique_ocachefile(tmppath_so::String, ocachefile_orig::String, ocachefile::String = ocachefile_orig, num = 1)
2929+
try
2930+
rename(tmppath_so, ocachefile; force=true)
2931+
catch e
2932+
e isa IOError || rethrow()
2933+
# If `rm` was called on a dir containing a loaded DLL, we moved it to temp for cleanup
2934+
# on restart. However the old path cannot be used (UV_EACCES) while the DLL is loaded
2935+
if !isfile(ocachefile) && e.code != Base.UV_EACCES
2936+
rethrow()
2937+
end
2938+
# Windows prevents renaming a file that is in use so if there is a Julia session started
2939+
# with a package image loaded, we cannot rename that file.
2940+
# The code belows append a `_i` to the name of the cache file where `i` is the smallest number such that
2941+
# that cache file does not exist.
2942+
ocachename, ocacheext = splitext(ocachefile_orig)
2943+
ocachefile_unique = ocachename * "_$num" * ocacheext
2944+
ocachefile = rename_unique_ocachefile(tmppath_so, ocachefile_orig, ocachefile_unique, num + 1)
2945+
end
2946+
return ocachefile
2947+
end
2948+
29482949
function module_build_id(m::Module)
29492950
hi, lo = ccall(:jl_module_build_id, NTuple{2,UInt64}, (Any,), m)
29502951
return (UInt128(hi) << 64) | lo

0 commit comments

Comments
 (0)