@@ -118,22 +118,26 @@ end
118
118
unsafe_convert (:: Type{Ptr{Cvoid}} , t:: Timer ) = t. handle
119
119
unsafe_convert (:: Type{Ptr{Cvoid}} , async:: AsyncCondition ) = async. handle
120
120
121
+ # if this returns true, the object has been signaled
122
+ # if this returns false, the object is closed
121
123
function _trywait (t:: Union{Timer, AsyncCondition} )
122
124
set = t. set
123
125
if set
124
126
# full barrier now for AsyncCondition
125
127
t isa Timer || Core. Intrinsics. atomic_fence (:acquire_release )
126
128
else
127
- t. isopen || return false
128
- t. handle == C_NULL && return false
129
+ if ! isopen (t)
130
+ close (t) # wait for the close to complete
131
+ return false
132
+ end
129
133
iolock_begin ()
130
134
set = t. set
131
135
if ! set
132
136
preserve_handle (t)
133
137
lock (t. cond)
134
138
try
135
139
set = t. set
136
- if ! set && t. isopen && t . handle != C_NULL
140
+ if ! set && t. handle != C_NULL # wait for set or handle, but not the isopen flag
137
141
iolock_end ()
138
142
set = wait (t. cond)
139
143
unlock (t. cond)
@@ -160,10 +164,28 @@ end
160
164
isopen (t:: Union{Timer, AsyncCondition} ) = t. isopen && t. handle != C_NULL
161
165
162
166
function close (t:: Union{Timer, AsyncCondition} )
167
+ t. handle == C_NULL && return # short-circuit path
163
168
iolock_begin ()
164
- if isopen (t)
165
- @atomic :monotonic t. isopen = false
166
- ccall (:jl_close_uv , Cvoid, (Ptr{Cvoid},), t)
169
+ if t. handle != C_NULL
170
+ if t. isopen
171
+ @atomic :monotonic t. isopen = false
172
+ ccall (:jl_close_uv , Cvoid, (Ptr{Cvoid},), t)
173
+ end
174
+ # implement _trywait here without the auto-reset function, just waiting for the final close signal
175
+ preserve_handle (t)
176
+ lock (t. cond)
177
+ try
178
+ while t. handle != C_NULL
179
+ iolock_end ()
180
+ wait (t. cond)
181
+ unlock (t. cond)
182
+ iolock_begin ()
183
+ lock (t. cond)
184
+ end
185
+ finally
186
+ unlock (t. cond)
187
+ unpreserve_handle (t)
188
+ end
167
189
end
168
190
iolock_end ()
169
191
nothing
@@ -220,7 +242,10 @@ function uv_timercb(handle::Ptr{Cvoid})
220
242
@atomic :monotonic t. set = true
221
243
if ccall (:uv_timer_get_repeat , UInt64, (Ptr{Cvoid},), t) == 0
222
244
# timer is stopped now
223
- close (t)
245
+ if t. isopen
246
+ @atomic :monotonic t. isopen = false
247
+ ccall (:jl_close_uv , Cvoid, (Ptr{Cvoid},), t)
248
+ end
224
249
end
225
250
notify (t. cond, true )
226
251
finally
0 commit comments