Skip to content

Commit 2bc291a

Browse files
lgeissbauer-btigKristofferC
authored andcommitted
don't throw EOFError from sleep (#54955)
(cherry picked from commit b049f93)
1 parent d9906cf commit 2bc291a

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

base/asyncevent.jl

+18-11
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,11 @@ function _trywait(t::Union{Timer, AsyncCondition})
127127
t isa Timer || Core.Intrinsics.atomic_fence(:acquire_release)
128128
else
129129
if !isopen(t)
130-
close(t) # wait for the close to complete
131-
return false
130+
set = t.set
131+
if !set
132+
close(t) # wait for the close to complete
133+
return false
134+
end
132135
end
133136
iolock_begin()
134137
set = t.set
@@ -151,7 +154,7 @@ function _trywait(t::Union{Timer, AsyncCondition})
151154
end
152155
iolock_end()
153156
end
154-
@atomic :monotonic t.set = false
157+
@atomic :monotonic t.set = false # if there are multiple waiters, an unspecified number may short-circuit past here
155158
return set
156159
end
157160

@@ -161,14 +164,14 @@ function wait(t::Union{Timer, AsyncCondition})
161164
end
162165

163166

164-
isopen(t::Union{Timer, AsyncCondition}) = t.isopen && t.handle != C_NULL
167+
isopen(t::Union{Timer, AsyncCondition}) = @atomic :acquire t.isopen
165168

166169
function close(t::Union{Timer, AsyncCondition})
167-
t.handle == C_NULL && return # short-circuit path
170+
t.handle == C_NULL && !t.isopen && return # short-circuit path, :monotonic
168171
iolock_begin()
169172
if t.handle != C_NULL
170173
if t.isopen
171-
@atomic :monotonic t.isopen = false
174+
@atomic :release t.isopen = false
172175
ccall(:jl_close_uv, Cvoid, (Ptr{Cvoid},), t)
173176
end
174177
# implement _trywait here without the auto-reset function, just waiting for the final close signal
@@ -186,6 +189,8 @@ function close(t::Union{Timer, AsyncCondition})
186189
unlock(t.cond)
187190
unpreserve_handle(t)
188191
end
192+
elseif t.isopen
193+
@atomic :release t.isopen = false
189194
end
190195
iolock_end()
191196
nothing
@@ -198,8 +203,8 @@ function uvfinalize(t::Union{Timer, AsyncCondition})
198203
if t.handle != C_NULL
199204
disassociate_julia_struct(t.handle) # not going to call the usual close hooks anymore
200205
if t.isopen
201-
@atomic :monotonic t.isopen = false
202-
ccall(:jl_close_uv, Cvoid, (Ptr{Cvoid},), t.handle)
206+
@atomic :release t.isopen = false
207+
ccall(:jl_close_uv, Cvoid, (Ptr{Cvoid},), t.handle) # this will call Libc.free
203208
end
204209
@atomic :monotonic t.handle = C_NULL
205210
notify(t.cond, false)
@@ -214,8 +219,10 @@ end
214219
function _uv_hook_close(t::Union{Timer, AsyncCondition})
215220
lock(t.cond)
216221
try
217-
@atomic :monotonic t.isopen = false
218-
Libc.free(@atomicswap :monotonic t.handle = C_NULL)
222+
handle = t.handle
223+
@atomic :release t.isopen = false
224+
@atomic :monotonic t.handle = C_NULL
225+
Libc.free(handle)
219226
notify(t.cond, false)
220227
finally
221228
unlock(t.cond)
@@ -243,7 +250,7 @@ function uv_timercb(handle::Ptr{Cvoid})
243250
if ccall(:uv_timer_get_repeat, UInt64, (Ptr{Cvoid},), t) == 0
244251
# timer is stopped now
245252
if t.isopen
246-
@atomic :monotonic t.isopen = false
253+
@atomic :release t.isopen = false
247254
ccall(:jl_close_uv, Cvoid, (Ptr{Cvoid},), t)
248255
end
249256
end

0 commit comments

Comments
 (0)