Commit bb29cbb
committed
src: fix task queue deadlock when built as C++23
Since #65353, FlushForegroundTasksInternal() and the DelayedTaskScheduler
drain their queues with `for (auto& task : queue.Lock().PopAll())`. In
C++20 the Locked temporary is destroyed at the end of the range
initializer, before the loop body runs. C++23 (P2718R0) extends the
lifetime of every temporary in a range-for initializer to the end of
the loop, so the queue's mutex stays held while the tasks run, and the
first task that posts to the same queue - any V8 foreground task that
schedules another one - deadlocks on the non-recursive mutex. Node.js
itself builds with -std=gnu++20, but an embedder that compiles it as
C++23 hangs in the first foreground task flush.
Store the drained tasks in a local before iterating so the lock is
released independent of the language version.
Refs: #65353
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>1 parent 67e66b8 commit bb29cbb
2 files changed
Lines changed: 12 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
159 | 159 | | |
160 | 160 | | |
161 | 161 | | |
162 | | - | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
163 | 165 | | |
164 | 166 | | |
165 | 167 | | |
| |||
605 | 607 | | |
606 | 608 | | |
607 | 609 | | |
608 | | - | |
609 | | - | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
610 | 613 | | |
611 | 614 | | |
612 | 615 | | |
| |||
629 | 632 | | |
630 | 633 | | |
631 | 634 | | |
632 | | - | |
633 | | - | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
634 | 638 | | |
635 | 639 | | |
636 | 640 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
39 | 41 | | |
40 | 42 | | |
41 | 43 | | |
| |||
0 commit comments