Skip to content

Commit 2d9e9b7

Browse files
vtjnashericphanson
authored andcommitted
Check for timer isopen correctly (JuliaLang#162)
(cherry picked from commit 4250b35)
1 parent 1dbb654 commit 2d9e9b7

File tree

1 file changed

+30
-16
lines changed

1 file changed

+30
-16
lines changed

src/Curl/Multi.jl

+30-16
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
mutable struct Multi
22
lock :: ReentrantLock
33
handle :: Ptr{Cvoid}
4-
timer :: Timer
4+
timer :: Union{Nothing,Timer}
55
easies :: Vector{Easy}
66
grace :: UInt64
77

88
function Multi(grace::Integer = typemax(UInt64))
9-
multi = new(ReentrantLock(), C_NULL, Timer(0), Easy[], grace)
10-
finalizer(multi) do multi
11-
close(multi.timer)
12-
done!(multi)
13-
end
9+
multi = new(ReentrantLock(), C_NULL, nothing, Easy[], grace)
10+
finalizer(done!, multi)
11+
return multi
1412
end
1513
end
1614

@@ -19,12 +17,25 @@ function init!(multi::Multi)
1917
multi.handle = curl_multi_init()
2018
add_callbacks(multi)
2119
set_defaults(multi)
20+
nothing
2221
end
2322

2423
function done!(multi::Multi)
25-
multi.handle == C_NULL && return
26-
curl_multi_cleanup(multi.handle)
24+
stoptimer!(multi)
25+
handle = multi.handle
26+
handle == C_NULL && return
2727
multi.handle = C_NULL
28+
curl_multi_cleanup(handle)
29+
nothing
30+
end
31+
32+
function stoptimer!(multi::Multi)
33+
t = multi.timer
34+
if t !== nothing
35+
multi.timer = nothing
36+
close(t)
37+
end
38+
nothing
2839
end
2940

3041
# adding & removing easy handles
@@ -33,7 +44,6 @@ function add_handle(multi::Multi, easy::Easy)
3344
lock(multi.lock) do
3445
if isempty(multi.easies)
3546
preserve_handle(multi)
36-
close(multi.timer) # stop grace timer
3747
end
3848
push!(multi.easies, easy)
3949
init!(multi)
@@ -45,13 +55,16 @@ function remove_handle(multi::Multi, easy::Easy)
4555
lock(multi.lock) do
4656
@check curl_multi_remove_handle(multi.handle, easy.handle)
4757
deleteat!(multi.easies, findlast(==(easy), multi.easies)::Int)
48-
!isempty(multi.easies) && return
58+
isempty(multi.easies) || return
59+
stoptimer!(multi)
4960
if multi.grace <= 0
5061
done!(multi)
5162
elseif 0 < multi.grace < typemax(multi.grace)
5263
multi.timer = Timer(multi.grace/1000) do timer
5364
lock(multi.lock) do
54-
isopen(timer) && done!(multi)
65+
multi.timer === timer || return
66+
multi.timer = nothing
67+
done!(multi)
5568
end
5669
end
5770
end
@@ -108,18 +121,19 @@ function timer_callback(
108121
multi_p :: Ptr{Cvoid},
109122
)::Cint
110123
multi = unsafe_pointer_to_objref(multi_p)::Multi
111-
@assert multi_h == multi.handle
124+
@assert multi_h == multi.handle
125+
stoptimer!(multi)
112126
if timeout_ms == 0
113127
do_multi(multi)
114128
elseif timeout_ms >= 0
115129
multi.timer = Timer(timeout_ms/1000) do timer
116130
lock(multi.lock) do
117-
isopen(timer) && do_multi(multi)
131+
multi.timer === timer || return
132+
multi.timer = nothing
133+
do_multi(multi)
118134
end
119135
end
120-
elseif timeout_ms == -1
121-
close(multi.timer)
122-
else
136+
elseif timeout_ms != -1
123137
@async @error("timer_callback: invalid timeout value", timeout_ms)
124138
return -1
125139
end

0 commit comments

Comments
 (0)