Skip to content

Commit 7d65e13

Browse files
authored
fix #32903, regression in Ctrl-C after adding io locks (#33031)
1 parent 0c209e2 commit 7d65e13

File tree

5 files changed

+32
-2
lines changed

5 files changed

+32
-2
lines changed

base/condition.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ function wait(c::GenericCondition)
106106
try
107107
return wait()
108108
catch
109-
list_deletefirst!(c.waitq, ct)
109+
ct.queue === nothing || list_deletefirst!(ct.queue, ct)
110110
rethrow()
111111
finally
112112
relockall(c.lock, token)

base/stream.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,15 +924,20 @@ function uv_write(s::LibuvStream, p::Ptr{UInt8}, n::UInt)
924924
uvw = uv_write_async(s, p, n)
925925
ct = current_task()
926926
preserve_handle(ct)
927+
sigatomic_begin()
927928
uv_req_set_data(uvw, ct)
928929
iolock_end()
929930
status = try
931+
sigatomic_end()
930932
# wait for the last chunk to complete (or error)
931933
# assume that any errors would be sticky,
932934
# (so we don't need to monitor the error status of the intermediate writes)
933935
wait()::Cint
934936
finally
937+
# try-finally unwinds the sigatomic level, so need to repeat sigatomic_end
938+
sigatomic_end()
935939
iolock_begin()
940+
ct.queue === nothing || list_deletefirst!(ct.queue, ct)
936941
if uv_req_data(uvw) != C_NULL
937942
# uvw is still alive,
938943
# so make sure we won't get spurious notifications later

base/task.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,16 @@ Switch to the scheduler to allow another scheduled task to run. A task that call
561561
function is still runnable, and will be restarted immediately if there are no other runnable
562562
tasks.
563563
"""
564-
yield() = (enq_work(current_task()); wait())
564+
function yield()
565+
ct = current_task()
566+
enq_work(ct)
567+
try
568+
wait()
569+
catch
570+
ct.queue === nothing || list_deletefirst!(ct.queue, ct)
571+
rethrow()
572+
end
573+
end
565574

566575
"""
567576
yield(t::Task, arg = nothing)

stdlib/Sockets/src/Sockets.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,12 +434,16 @@ function send(sock::UDPSocket, ipaddr::IPAddr, port::Integer, msg)
434434
uvw = _send_async(sock, ipaddr, UInt16(port), msg)
435435
ct = current_task()
436436
preserve_handle(ct)
437+
Base.sigatomic_begin()
437438
uv_req_set_data(uvw, ct)
438439
iolock_end()
439440
status = try
441+
Base.sigatomic_end()
440442
wait()::Cint
441443
finally
444+
Base.sigatomic_end()
442445
iolock_begin()
446+
ct.queue === nothing || list_deletefirst!(ct.queue, ct)
443447
if uv_req_data(uvw) != C_NULL
444448
# uvw is still alive,
445449
# so make sure we won't get spurious notifications later

stdlib/Sockets/src/addrinfo.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,16 @@ function getalladdrinfo(host::String)
7373
end
7474
ct = current_task()
7575
preserve_handle(ct)
76+
Base.sigatomic_begin()
7677
uv_req_set_data(req, ct)
7778
iolock_end()
7879
r = try
80+
Base.sigatomic_end()
7981
wait()
8082
finally
83+
Base.sigatomic_end()
84+
iolock_begin()
85+
ct.queue === nothing || list_deletefirst!(ct.queue, ct)
8186
if uv_req_data(req) != C_NULL
8287
# req is still alive,
8388
# so make sure we don't get spurious notifications later
@@ -87,6 +92,7 @@ function getalladdrinfo(host::String)
8792
# done with req
8893
Libc.free(req)
8994
end
95+
iolock_end()
9096
unpreserve_handle(ct)
9197
end
9298
if isa(r, IOError)
@@ -176,11 +182,16 @@ function getnameinfo(address::Union{IPv4, IPv6})
176182
end
177183
ct = current_task()
178184
preserve_handle(ct)
185+
Base.sigatomic_begin()
179186
uv_req_set_data(req, ct)
180187
iolock_end()
181188
r = try
189+
Base.sigatomic_end()
182190
wait()
183191
finally
192+
Base.sigatomic_end()
193+
iolock_begin()
194+
ct.queue === nothing || list_deletefirst!(ct.queue, ct)
184195
if uv_req_data(req) != C_NULL
185196
# req is still alive,
186197
# so make sure we don't get spurious notifications later
@@ -190,6 +201,7 @@ function getnameinfo(address::Union{IPv4, IPv6})
190201
# done with req
191202
Libc.free(req)
192203
end
204+
iolock_end()
193205
unpreserve_handle(ct)
194206
end
195207
if isa(r, IOError)

0 commit comments

Comments
 (0)