1
1
mutable struct Multi
2
2
lock :: ReentrantLock
3
3
handle :: Ptr{Cvoid}
4
- timer :: Timer
4
+ timer :: Union{Nothing, Timer}
5
5
easies :: Vector{Easy}
6
6
grace :: UInt64
7
7
8
8
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
14
12
end
15
13
end
16
14
@@ -19,12 +17,25 @@ function init!(multi::Multi)
19
17
multi. handle = curl_multi_init ()
20
18
add_callbacks (multi)
21
19
set_defaults (multi)
20
+ nothing
22
21
end
23
22
24
23
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
27
27
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
28
39
end
29
40
30
41
# adding & removing easy handles
@@ -33,7 +44,6 @@ function add_handle(multi::Multi, easy::Easy)
33
44
lock (multi. lock) do
34
45
if isempty (multi. easies)
35
46
preserve_handle (multi)
36
- close (multi. timer) # stop grace timer
37
47
end
38
48
push! (multi. easies, easy)
39
49
init! (multi)
@@ -45,13 +55,16 @@ function remove_handle(multi::Multi, easy::Easy)
45
55
lock (multi. lock) do
46
56
@check curl_multi_remove_handle (multi. handle, easy. handle)
47
57
deleteat! (multi. easies, findlast (== (easy), multi. easies):: Int )
48
- ! isempty (multi. easies) && return
58
+ isempty (multi. easies) || return
59
+ stoptimer! (multi)
49
60
if multi. grace <= 0
50
61
done! (multi)
51
62
elseif 0 < multi. grace < typemax (multi. grace)
52
63
multi. timer = Timer (multi. grace/ 1000 ) do timer
53
64
lock (multi. lock) do
54
- isopen (timer) && done! (multi)
65
+ multi. timer === timer || return
66
+ multi. timer = nothing
67
+ done! (multi)
55
68
end
56
69
end
57
70
end
@@ -108,18 +121,19 @@ function timer_callback(
108
121
multi_p :: Ptr{Cvoid} ,
109
122
):: Cint
110
123
multi = unsafe_pointer_to_objref (multi_p):: Multi
111
- @assert multi_h == multi. handle
124
+ @assert multi_h == multi. handle
125
+ stoptimer! (multi)
112
126
if timeout_ms == 0
113
127
do_multi (multi)
114
128
elseif timeout_ms >= 0
115
129
multi. timer = Timer (timeout_ms/ 1000 ) do timer
116
130
lock (multi. lock) do
117
- isopen (timer) && do_multi (multi)
131
+ multi. timer === timer || return
132
+ multi. timer = nothing
133
+ do_multi (multi)
118
134
end
119
135
end
120
- elseif timeout_ms == - 1
121
- close (multi. timer)
122
- else
136
+ elseif timeout_ms != - 1
123
137
@async @error (" timer_callback: invalid timeout value" , timeout_ms)
124
138
return - 1
125
139
end
0 commit comments