Skip to content

Commit

Permalink
Check for timer isopen correctly (JuliaLang#162)
Browse files Browse the repository at this point in the history
(cherry picked from commit 4250b35)
  • Loading branch information
vtjnash authored and ericphanson committed Jan 27, 2022
1 parent 1dbb654 commit 2d9e9b7
Showing 1 changed file with 30 additions and 16 deletions.
46 changes: 30 additions & 16 deletions src/Curl/Multi.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
mutable struct Multi
lock :: ReentrantLock
handle :: Ptr{Cvoid}
timer :: Timer
timer :: Union{Nothing,Timer}
easies :: Vector{Easy}
grace :: UInt64

function Multi(grace::Integer = typemax(UInt64))
multi = new(ReentrantLock(), C_NULL, Timer(0), Easy[], grace)
finalizer(multi) do multi
close(multi.timer)
done!(multi)
end
multi = new(ReentrantLock(), C_NULL, nothing, Easy[], grace)
finalizer(done!, multi)
return multi
end
end

Expand All @@ -19,12 +17,25 @@ function init!(multi::Multi)
multi.handle = curl_multi_init()
add_callbacks(multi)
set_defaults(multi)
nothing
end

function done!(multi::Multi)
multi.handle == C_NULL && return
curl_multi_cleanup(multi.handle)
stoptimer!(multi)
handle = multi.handle
handle == C_NULL && return
multi.handle = C_NULL
curl_multi_cleanup(handle)
nothing
end

function stoptimer!(multi::Multi)
t = multi.timer
if t !== nothing
multi.timer = nothing
close(t)
end
nothing
end

# adding & removing easy handles
Expand All @@ -33,7 +44,6 @@ function add_handle(multi::Multi, easy::Easy)
lock(multi.lock) do
if isempty(multi.easies)
preserve_handle(multi)
close(multi.timer) # stop grace timer
end
push!(multi.easies, easy)
init!(multi)
Expand All @@ -45,13 +55,16 @@ function remove_handle(multi::Multi, easy::Easy)
lock(multi.lock) do
@check curl_multi_remove_handle(multi.handle, easy.handle)
deleteat!(multi.easies, findlast(==(easy), multi.easies)::Int)
!isempty(multi.easies) && return
isempty(multi.easies) || return
stoptimer!(multi)
if multi.grace <= 0
done!(multi)
elseif 0 < multi.grace < typemax(multi.grace)
multi.timer = Timer(multi.grace/1000) do timer
lock(multi.lock) do
isopen(timer) && done!(multi)
multi.timer === timer || return
multi.timer = nothing
done!(multi)
end
end
end
Expand Down Expand Up @@ -108,18 +121,19 @@ function timer_callback(
multi_p :: Ptr{Cvoid},
)::Cint
multi = unsafe_pointer_to_objref(multi_p)::Multi
@assert multi_h == multi.handle
@assert multi_h == multi.handle
stoptimer!(multi)
if timeout_ms == 0
do_multi(multi)
elseif timeout_ms >= 0
multi.timer = Timer(timeout_ms/1000) do timer
lock(multi.lock) do
isopen(timer) && do_multi(multi)
multi.timer === timer || return
multi.timer = nothing
do_multi(multi)
end
end
elseif timeout_ms == -1
close(multi.timer)
else
elseif timeout_ms != -1
@async @error("timer_callback: invalid timeout value", timeout_ms)
return -1
end
Expand Down

0 comments on commit 2d9e9b7

Please sign in to comment.