diff --git a/base/task.jl b/base/task.jl index 1ed68f70f7ab7..bfb105accef14 100644 --- a/base/task.jl +++ b/base/task.jl @@ -621,6 +621,12 @@ function enq_work(t::Task) # 3. The multiq is full (can be fixed by making it growable). if t.sticky || Threads.nthreads() == 1 if tid == 0 + # Issue #41324 + # t.sticky && tid == 0 is a task that needs to be co-scheduled with + # the parent task. If the parent (current_task) is not sticky we must + # set it to be sticky. + # XXX: Ideally we would be able to unset this + current_task().sticky = true tid = Threads.threadid() ccall(:jl_set_task_tid, Cvoid, (Any, Cint), t, tid-1) end diff --git a/test/threads_exec.jl b/test/threads_exec.jl index b7e4c37631d83..a0cac726b8e27 100644 --- a/test/threads_exec.jl +++ b/test/threads_exec.jl @@ -840,6 +840,18 @@ fib34666(x) = end @test fib34666(25) == 75025 +# issue #41324 +@testset "Co-schedule" begin + parent = Threads.@spawn begin + @test current_task().sticky == false + child = @async begin end + @test current_task().sticky == true + wait(child) + end + wait(parent) + @test parent.sticky == true +end + function jitter_channel(f, k, delay, ntasks, schedule) x = Channel(ch -> foreach(i -> put!(ch, i), 1:k), 1) y = Channel(k) do ch