Skip to content

Commit bc91453

Browse files
committed
Include review comments and move obsolete DLLs out of depot
1 parent d7034e5 commit bc91453

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

base/file.jl

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,9 @@ function mkpath(path::AbstractString; mode::Integer = 0o777)
253253
return path
254254
end
255255

256-
# Files that were requested to be deleted but can't be by the current process
257-
# i.e. loaded DLLs on Windows
258-
delayed_delete_list() = joinpath(tempdir(), "julia_delayed_deletes.txt")
256+
# Files that were requested to be deleted but can't be by the current process,
257+
# i.e. loaded DLLs on Windows, are listed in the directory below
258+
delayed_delete_ref() = joinpath(tempdir(), "julia_delayed_deletes_ref")
259259

260260
"""
261261
rm(path::AbstractString; force::Bool=false, recursive::Bool=false)
@@ -278,24 +278,17 @@ Stacktrace:
278278
[...]
279279
```
280280
"""
281-
function rm(path::AbstractString; force::Bool=false, recursive::Bool=false)
281+
function rm(path::AbstractString; force::Bool=false, recursive::Bool=false, allow_delayed_delete::Bool=true)
282+
# allow_delayed_delete is used by Pkg.gc() but is otherwise not part of the public API
282283
if islink(path) || !isdir(path)
283284
try
284285
unlink(path)
285286
catch err
286287
if isa(err, IOError)
287288
force && err.code==Base.UV_ENOENT && return
288289
@static if Sys.iswindows()
289-
if err.code==Base.UV_EACCES && endswith(path, ".dll")
290-
# Loaded DLLs cannot be deleted on Windows, even with posix delete mode
291-
# but they can be renamed. Do so temporarily, until later cleanup by Pkg.gc()
292-
temp_path = tempname(dirname(path), cleanup = false, suffix = string("_", basename(path)))
293-
# ensure that temp_path is on the same drive as path to avoid issue #59589
294-
@debug "Could not delete DLL most likely because it is loaded, moving to a temporary path" path temp_path
295-
Base.open(delayed_delete_list(), "a") do io
296-
println(io, abspath(temp_path)) # record the temporary path for Pkg.gc()
297-
end
298-
rename(path, temp_path) # do not call mv which could recursively call rm(path)
290+
if allow_delayed_delete && err.code==Base.UV_EACCES && endswith(path, ".dll")
291+
delayed_delete_dll(path)
299292
return
300293
end
301294
end
@@ -331,6 +324,27 @@ function rm(path::AbstractString; force::Bool=false, recursive::Bool=false)
331324
end
332325

333326

327+
# Loaded DLLs cannot be deleted on Windows, even with posix delete mode but they can be renamed.
328+
# delayed_delete_dll(path) does so temporarily, until later cleanup by Pkg.gc().
329+
function delayed_delete_dll(path)
330+
drive = first(splitdrive(path))
331+
tmpdrive = first(splitdrive(tempdir()))
332+
# in-use DLL must be kept on the same drive
333+
deletedir = if drive == tmpdrive
334+
joinpath(tempdir(), "julia_delayed_deletes")
335+
else
336+
joinpath(drive, "julia_delayed_deletes")
337+
end
338+
mkpath(deletedir)
339+
temp_path = tempname(deletedir; cleanup=false, suffix=string("_", basename(path)))
340+
@debug "Could not delete DLL most likely because it is loaded, moving to a temporary path" path temp_path
341+
mkpath(delayed_delete_ref())
342+
io = last(mktemp(delayed_delete_ref(); cleanup=false))
343+
println(io, abspath(temp_path)) # record the temporary path for Pkg.gc()
344+
close(io)
345+
rename(path, temp_path) # do not call mv which could recursively call rm(path)
346+
end
347+
334348
# The following use Unix command line facilities
335349
function checkfor_mv_cp_cptree(src::AbstractString, dst::AbstractString, txt::AbstractString;
336350
force::Bool=false)

0 commit comments

Comments
 (0)