@@ -253,9 +253,9 @@ function mkpath(path::AbstractString; mode::Integer = 0o777)
253
253
return path
254
254
end
255
255
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 " )
259
259
260
260
"""
261
261
rm(path::AbstractString; force::Bool=false, recursive::Bool=false)
@@ -278,24 +278,17 @@ Stacktrace:
278
278
[...]
279
279
```
280
280
"""
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
282
283
if islink (path) || ! isdir (path)
283
284
try
284
285
unlink (path)
285
286
catch err
286
287
if isa (err, IOError)
287
288
force && err. code== Base. UV_ENOENT && return
288
289
@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)
299
292
return
300
293
end
301
294
end
@@ -331,6 +324,27 @@ function rm(path::AbstractString; force::Bool=false, recursive::Bool=false)
331
324
end
332
325
333
326
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
+
334
348
# The following use Unix command line facilities
335
349
function checkfor_mv_cp_cptree (src:: AbstractString , dst:: AbstractString , txt:: AbstractString ;
336
350
force:: Bool = false )
0 commit comments