diff --git a/base/channels.jl b/base/channels.jl index 66c73c9e3310e..0298ca6ade049 100644 --- a/base/channels.jl +++ b/base/channels.jl @@ -437,9 +437,9 @@ immediately, does not block. For unbuffered channels returns `true` if there are tasks waiting on a [`put!`](@ref). """ -isready(c::Channel) = length(c) > 0 -isempty(c::Channel) = length(c) == 0 -function length(c::Channel) +isready(c::Channel) = n_avail(c) > 0 +isempty(c::Channel) = n_avail(c) == 0 +function n_avail(c::Channel) # Lock-free equivalent to `length(c.data) + length(c.cond_put.waitq)` @atomic :monotonic c.length end @@ -473,7 +473,7 @@ function show(io::IO, ::MIME"text/plain", c::Channel) if !isopen(c) print(io, " (closed)") else - n = length(c) + n = n_avail(c) if n == 0 print(io, " (empty)") else diff --git a/test/channels.jl b/test/channels.jl index a7447cd01e4c7..e9f67bbfa350d 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -2,6 +2,7 @@ using Random using Base: Experimental +using Base: n_avail @testset "single-threaded Condition usage" begin a = Condition() @@ -579,38 +580,38 @@ let c = Channel(3) @test repr(MIME("text/plain"), c) == "Channel{Any}(3) (closed)" end -# PR #41833 - length(c) -@testset "length(::Channel)" begin - # Buffered: length() = buffer length + number of waiting tasks +# PR #41833 +@testset "n_avail(::Channel)" begin + # Buffered: n_avail() = buffer length + number of waiting tasks let c = Channel(2) - @test length(c) == 0; put!(c, 0) - @test length(c) == 1; put!(c, 0) - @test length(c) == 2; yield(@task put!(c, 0)) - @test length(c) == 3; yield(@task put!(c, 0)) - @test length(c) == 4 - # Test length(c) after interrupting a task waiting on the channel + @test n_avail(c) == 0; put!(c, 0) + @test n_avail(c) == 1; put!(c, 0) + @test n_avail(c) == 2; yield(@task put!(c, 0)) + @test n_avail(c) == 3; yield(@task put!(c, 0)) + @test n_avail(c) == 4 + # Test n_avail(c) after interrupting a task waiting on the channel t = @task put!(c, 0) yield(t) - @test length(c) == 5 + @test n_avail(c) == 5 @async Base.throwto(t, ErrorException("Exit put!")) try wait(t) catch end - @test length(c) == 4 + @test n_avail(c) == 4 close(c); yield() - @test length(c) == 2 # Already-buffered items remain + @test n_avail(c) == 2 # Already-buffered items remain end - # Unbuffered: length() = number of waiting tasks + # Unbuffered: n_avail() = number of waiting tasks let c = Channel() - @test length(c) == 0; yield(@task put!(c, 0)) - @test length(c) == 1; yield(@task put!(c, 0)) - @test length(c) == 2 - # Test length(c) after interrupting a task waiting on the channel + @test n_avail(c) == 0; yield(@task put!(c, 0)) + @test n_avail(c) == 1; yield(@task put!(c, 0)) + @test n_avail(c) == 2 + # Test n_avail(c) after interrupting a task waiting on the channel t = @task put!(c, 0) yield(t) - @test length(c) == 3 + @test n_avail(c) == 3 @async Base.throwto(t, ErrorException("Exit put!")) try wait(t) catch end - @test length(c) == 2 + @test n_avail(c) == 2 close(c); yield() - @test length(c) == 0 + @test n_avail(c) == 0 end end