diff --git a/base/task.jl b/base/task.jl index 90f74441c7fbd..653153478108e 100644 --- a/base/task.jl +++ b/base/task.jl @@ -1040,11 +1040,15 @@ end A fast, unfair-scheduling version of `schedule(t, arg); yield()` which immediately yields to `t` before calling the scheduler. + +Throws a `ConcurrencyViolationError` if `t` is the currently running task. """ function yield(t::Task, @nospecialize(x=nothing)) - (t._state === task_state_runnable && t.queue === nothing) || error("yield: Task not runnable") + current = current_task() + t === current && throw(ConcurrencyViolationError("Cannot yield to currently running task!")) + (t._state === task_state_runnable && t.queue === nothing) || throw(ConcurrencyViolationError("yield: Task not runnable")) t.result = x - enq_work(current_task()) + enq_work(current) set_next_task(t) return try_yieldto(ensure_rescheduled) end diff --git a/test/misc.jl b/test/misc.jl index e870c7f491c13..4a09015b0dc88 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -253,10 +253,12 @@ end @test_throws ErrorException("deadlock detected: cannot wait on current task") wait(current_task()) +@test_throws ConcurrencyViolationError("Cannot yield to currently running task!") yield(current_task()) + # issue #41347 let t = @async 1 wait(t) - @test_throws ErrorException yield(t) + @test_throws ConcurrencyViolationError yield(t) end let t = @async error(42)