Skip to content

Commit

Permalink
Check channel state on iterate (#52981)
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobnissen authored Jan 13, 2025
1 parent b671c9d commit de1dba2
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 @@ -716,6 +716,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 de1dba2

Please sign in to comment.