Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions base/channels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@ end

closed_exception() = InvalidStateException("Channel is closed.", :closed)

isbuffered(c::Channel) = c.sz_max==0 ? false : true
isbuffered(@nospecialize(c::Channel)) = c.sz_max==0 ? false : true

function check_channel_state(c::Channel)
function check_channel_state(@nospecialize(c::Channel))
if !isopen(c)
# if the monotonic load succeed, now do an acquire fence
(@atomic :acquire c.state) === :open && concurrency_violation()
Expand All @@ -183,8 +183,8 @@ Close a channel. An exception (optionally given by `excp`), is thrown by:
* [`put!`](@ref) on a closed channel.
* [`take!`](@ref) and [`fetch`](@ref) on an empty, closed channel.
"""
close(c::Channel) = close(c, closed_exception()) # nospecialize on default arg seems to confuse makedocs
function close(c::Channel, @nospecialize(excp::Exception))
close(@nospecialize(c::Channel)) = close(c, closed_exception()) # nospecialize on default arg seems to confuse makedocs
function close(@nospecialize(c::Channel), @nospecialize(excp::Exception))
lock(c)
try
c.excp = excp
Expand All @@ -197,7 +197,7 @@ function close(c::Channel, @nospecialize(excp::Exception))
end
nothing
end
isopen(c::Channel) = ((@atomic :monotonic c.state) === :open)
isopen(@nospecialize(c::Channel)) = ((@atomic :monotonic c.state) === :open)

"""
bind(chnl::Channel, task::Task)
Expand Down Expand Up @@ -251,7 +251,7 @@ Stacktrace:
[...]
```
"""
function bind(c::Channel, task::Task)
function bind(@nospecialize(c::Channel), @nospecialize(task::Task))
T = Task(() -> close_chnl_on_taskdone(task, c))
_wait2(task, T)
return c
Expand Down Expand Up @@ -283,7 +283,7 @@ function channeled_tasks(n::Int, funcs...; ctypes=fill(Any,n), csizes=fill(0,n))
return (chnls, tasks)
end

function close_chnl_on_taskdone(t::Task, c::Channel)
function close_chnl_on_taskdone(@nospecialize(task::Task), @nospecialize(c::Channel))
isopen(c) || return
lock(c)
try
Expand Down Expand Up @@ -323,7 +323,7 @@ function put!(c::Channel{T}, v) where T
end

# Atomically update channel n_avail, *assuming* we hold the channel lock.
function _increment_n_avail(c, inc)
function _increment_n_avail(@nospecialize(c), @nospecialize(inc))
# We hold the channel lock so it's safe to non-atomically read and
# increment c.n_avail_items
newlen = c.n_avail_items + inc
Expand Down Expand Up @@ -516,17 +516,17 @@ true
```

"""
isready(c::Channel) = n_avail(c) > 0
isempty(c::Channel) = n_avail(c) == 0
function n_avail(c::Channel)
isready(@nospecialize(c::Channel)) = n_avail(c) > 0
isempty(@nospecialize(c::Channel)) = n_avail(c) == 0
function n_avail(@nospecialize(c::Channel))
# Lock-free equivalent to `length(c.data) + length(c.cond_put.waitq)`
@atomic :monotonic c.n_avail_items
end

lock(c::Channel) = lock(c.cond_take)
lock(f, c::Channel) = lock(f, c.cond_take)
unlock(c::Channel) = unlock(c.cond_take)
trylock(c::Channel) = trylock(c.cond_take)
lock(@nospecialize(c::Channel)) = lock(c.cond_take)
lock(f, @nospecialize(c::Channel)) = lock(f, c.cond_take)
unlock(@nospecialize(c::Channel)) = unlock(c.cond_take)
trylock(@nospecialize(c::Channel)) = trylock(c.cond_take)

"""
wait(c::Channel)
Expand All @@ -552,7 +552,7 @@ julia> istaskdone(task) # task is now unblocked
true
```
"""
function wait(c::Channel)
function wait(@nospecialize(c::Channel))
isready(c) && return
lock(c)
try
Expand Down
1 change: 1 addition & 0 deletions contrib/generate_precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ precompile(Tuple{typeof(isassigned), Core.SimpleVector, Int})
precompile(Tuple{typeof(getindex), Core.SimpleVector, Int})
precompile(Tuple{typeof(Base.Experimental.register_error_hint), Any, Type})
precompile(Tuple{typeof(Base.display_error), Base.ExceptionStack})
precompile(Tuple{typeof(Base.close), Base.Channel, Exception})
precompile(Tuple{Core.kwftype(typeof(Type)), NamedTuple{(:sizehint,), Tuple{Int}}, Type{IOBuffer}})
precompile(Base.CoreLogging.current_logger_for_env, (Base.CoreLogging.LogLevel, String, Module))
precompile(Base.CoreLogging.current_logger_for_env, (Base.CoreLogging.LogLevel, Symbol, Module))
Expand Down