Skip to content

Commit a1adecb

Browse files
authored
Fix: waitall can throw when all tasks are done (#59905)
Closes #59901
1 parent f689446 commit a1adecb

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

base/task.jl

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -435,19 +435,21 @@ function _wait_multiple(waiting_tasks, throwexc=false, all=false, failfast=false
435435
done_mask[i] = true
436436
exception |= istaskfailed(t)
437437
nremaining -= 1
438-
else
439-
done_mask[i] = false
440438
end
441439
end
442440

443-
if nremaining == 0
444-
return tasks, Task[]
445-
elseif any(done_mask) && (!all || (failfast && exception))
441+
# We can return early all tasks are done, or if any is done and we only
442+
# needed to wait for one, or if any task failed and we have failfast
443+
if nremaining == 0 || (any(done_mask) && (!all || (failfast && exception)))
446444
if throwexc && (!all || failfast) && exception
447445
exceptions = [TaskFailedException(t) for t in tasks[done_mask] if istaskfailed(t)]
448446
throw(CompositeException(exceptions))
449447
else
450-
return tasks[done_mask], tasks[.~done_mask]
448+
if nremaining == 0
449+
return tasks, Task[]
450+
else
451+
return tasks[done_mask], tasks[.~done_mask]
452+
end
451453
end
452454
end
453455

@@ -489,6 +491,10 @@ function _wait_multiple(waiting_tasks, throwexc=false, all=false, failfast=false
489491
close(chan)
490492

491493
if nremaining == 0
494+
if throwexc && exception
495+
exceptions = [TaskFailedException(t) for t in tasks if istaskfailed(t)]
496+
throw(CompositeException(exceptions))
497+
end
492498
return tasks, Task[]
493499
else
494500
remaining_mask = .~done_mask

test/threads_exec.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,17 @@ end
13641364
@test !istaskdone(tasks[3])
13651365

13661366
teardown(tasks, event)
1367+
1368+
@test_throws CompositeException begin
1369+
waitall(Threads.@spawn(div(1, i)) for i = 0:1)
1370+
end
1371+
1372+
tasks = [Threads.@spawn(div(1, i)) for i = 0:1]
1373+
wait(tasks[1]; throw=false)
1374+
wait(tasks[2]; throw=false)
1375+
@test_throws CompositeException begin
1376+
waitall(Threads.@spawn(div(1, i)) for i = 0:1)
1377+
end
13671378
end
13681379
end
13691380
end

0 commit comments

Comments
 (0)