Skip to content

Commit

Permalink
Check task state on iterate
Browse files Browse the repository at this point in the history
Before, iterate on Channel would return `nothing` when the channel was closed,
not checking if it was closed with an error.
  • Loading branch information
jakobnissen committed Sep 9, 2024
1 parent 527fa1c commit e7d4ada
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
9 changes: 9 additions & 0 deletions base/channels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,15 @@ function iterate(c::Channel, state=nothing)
end
end
else
# If the channel was closed with an exception, it needs to be thrown
if (@atomic :acquire c.state) === :closed
e = c.excp
if isa(e, InvalidStateException) && e.state === :closed
nothing
else
throw(e)
end
end
return nothing
end
end
Expand Down
23 changes: 23 additions & 0 deletions test/channels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -499,12 +499,35 @@ end
end
end

struct CustomError <: Exception end

@testset "check_channel_state" begin
c = Channel(1)
close(c)
@test !isopen(c)
c.excp === nothing # to trigger the branch
@test_throws InvalidStateException Base.check_channel_state(c)

# Issue 52974 - closed channels with exceptions
# must be thrown on iteration, if channel is empty
c = Channel(2)
put!(c, 5)
close(c, CustomError())
@test take!(c) == 5
@test_throws CustomError iterate(c)

c = Channel(Inf)
put!(c, 1)
close(c)
@test take!(c) == 1
@test_throws InvalidStateException take!(c)
@test_throws InvalidStateException put!(c, 5)

c = Channel(3)
put!(c, 1)
close(c)
@test first(iterate(c)) == 1
@test isnothing(iterate(c))
end

# PR #36641
Expand Down

0 comments on commit e7d4ada

Please sign in to comment.