@@ -2902,26 +2902,10 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in
2902
2902
end
2903
2903
2904
2904
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 )
2905
+ ocachefile_new = rename_unique_ocachefile (tmppath_so, ocachefile)
2906
+ if ocachefile_new != ocachefile
2907
+ cachefile = cachefile_from_ocachefile (ocachefile_new)
2908
+ ocachefile = ocachefile_new
2925
2909
end
2926
2910
@static if Sys. isapple ()
2927
2911
run (` $(Linking. dsymutil ()) $ocachefile ` , Base. DevNull (), Base. DevNull (), Base. DevNull ())
@@ -2945,6 +2929,27 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in
2945
2929
end
2946
2930
end
2947
2931
2932
+ function rename_unique_ocachefile (tmppath_so:: String , ocachefile_orig:: String , ocachefile:: String = ocachefile_orig, num = 0 )
2933
+ try
2934
+ rename (tmppath_so, ocachefile; force= true )
2935
+ catch e
2936
+ e isa IOError || rethrow ()
2937
+ # If `rm` was called on a dir containing a loaded DLL, we moved it to temp for cleanup
2938
+ # on restart. However the old path cannot be used (UV_EACCES) while the DLL is loaded
2939
+ if ! isfile (ocachefile) && e. code != Base. UV_EACCES
2940
+ rethrow ()
2941
+ end
2942
+ # Windows prevents renaming a file that is in use so if there is a Julia session started
2943
+ # with a package image loaded, we cannot rename that file.
2944
+ # The code belows append a `_i` to the name of the cache file where `i` is the smallest number such that
2945
+ # that cache file does not exist.
2946
+ ocachename, ocacheext = splitext (ocachefile_orig)
2947
+ ocachefile_unique = ocachename * " _$num " * ocacheext
2948
+ ocachefile = rename_unique_ocachefile (tmppath_so, ocachefile_orig, ocachefile_unique, num + 1 )
2949
+ end
2950
+ return ocachefile
2951
+ end
2952
+
2948
2953
function module_build_id (m:: Module )
2949
2954
hi, lo = ccall (:jl_module_build_id , NTuple{2 ,UInt64}, (Any,), m)
2950
2955
return (UInt128 (hi) << 64 ) | lo
0 commit comments