From 20bdb161fad90b591a5d2ab8b0fd51ce00b04997 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 18 Jun 2020 14:23:33 -0400 Subject: [PATCH] FileWatching: cleanup timers on return (#36301) Following my own advice at #36217. Avoids a minor temporary resource leak. --- stdlib/FileWatching/src/FileWatching.jl | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/stdlib/FileWatching/src/FileWatching.jl b/stdlib/FileWatching/src/FileWatching.jl index 6f316e5a772f01..9e39ab25904791 100644 --- a/stdlib/FileWatching/src/FileWatching.jl +++ b/stdlib/FileWatching/src/FileWatching.jl @@ -649,10 +649,13 @@ giving the result of the polling. function poll_fd(s::Union{RawFD, Sys.iswindows() ? WindowsRawSocket : Union{}}, timeout_s::Real=-1; readable=false, writable=false) wt = Condition() fdw = _FDWatcher(s, readable, writable) + local timer try if timeout_s >= 0 result::FDEvent = FDEvent() - @async (sleep(timeout_s); notify(wt)) + timer = Timer(timeout_s) do t + notify(wt) + end @async begin try result = wait(fdw, readable=readable, writable=writable) @@ -669,6 +672,7 @@ function poll_fd(s::Union{RawFD, Sys.iswindows() ? WindowsRawSocket : Union{}}, end finally close(fdw, readable, writable) + @isdefined(timer) && close(timer) end end @@ -686,13 +690,17 @@ This behavior of this function varies slightly across platforms. See """ function watch_file(s::AbstractString, timeout_s::Real=-1) fm = FileMonitor(s) + local timer try if timeout_s >= 0 - @async (sleep(timeout_s); close(fm)) + timer = Timer(timeout_s) do t + close(fm) + end end return wait(fm) finally close(fm) + @isdefined(timer) && close(timer) end end @@ -730,14 +738,17 @@ function watch_folder(s::String, timeout_s::Real=-1) # create a second monitor object just for that purpose. # We still take the events from the primary stream. fm2 = FileMonitor(s) + timer = Timer(timeout_s) do t + close(fm2) + end try - @async (sleep(timeout_s); close(fm2)) while isopen(fm.notify) && !isready(fm.notify) fm2.handle == C_NULL && return "" => FileEvent() # timeout wait(fm2) end finally close(fm2) + close(timer) end # guaranteed that next call to `wait(fm)` is non-blocking # since we haven't entered the libuv event loop yet @@ -783,9 +794,12 @@ it is more reliable and efficient, although in some situations it may not be ava """ function poll_file(s::AbstractString, interval_seconds::Real=5.007, timeout_s::Real=-1) pfw = PollingFileWatcher(s, Float64(interval_seconds)) + local timer try if timeout_s >= 0 - @async (sleep(timeout_s); close(pfw)) + timer = Timer(timeout_s) do t + close(pfw) + end end statdiff = wait(pfw) if isa(statdiff[2], IOError) @@ -795,6 +809,7 @@ function poll_file(s::AbstractString, interval_seconds::Real=5.007, timeout_s::R return statdiff finally close(pfw) + @isdefined(timer) && close(timer) end end