[turbopack] Fix a potential deadlock in scope_and_block (#95695)
### What?
Fix a potential deadlock in `scope_and_block` (the CPU fan-out primitive
in `turbopack/crates/turbo-tasks/src/scope.rs`) by routing every job
through a single shared work queue, so completion never depends on a
spawned worker being scheduled.
### Why?
`scope_and_block` runs a batch of jobs across the tokio runtime's worker
threads while the calling thread blocks. Previously, jobs at indices
`1..=WORKER_TASKS` were handed *exclusively* to freshly `handle.spawn`ed
worker tasks and never placed on the shared queue — but the calling
thread only drains the queue, so it could not run those jobs itself.
Each spawned worker runs synchronous code and parks on a
`parking_lot::Condvar` (no `.await`, no `block_in_place`), so once
scheduled it holds its runtime core for the whole scope. When the
runtime has fewer worker threads than host CPUs, or they are already
occupied, those workers may never get a core. Their exclusively-assigned
jobs then never run, `remaining_tasks` never reaches 0, and the caller
blocks forever.
### How?
- **Every job goes on one shared queue.** Spawned helpers are now a pure
optimization that pull from the same queue; they are never assigned a
dedicated job. The calling thread drains the whole queue itself in
`end_and_help_complete`, so liveness never depends on a helper being
scheduled.
- **Runtime-accurate helper cap.** The helper count is
`num_workers().min(number_of_tasks) - 1` (per-scope, from
`Handle::current().metrics()`) instead of a process-global host-CPU
constant.
- **Close via a flag, not a sentinel.** The queue carries a `closed` bit
guarded by the same lock as the jobs. `end_and_help_complete` sets it
and `notify_all`s once; a drainer that finds the queue empty exits when
closed or parks otherwise. This replaces the previous `End` token that
had to be ping-ponged across drainers.
- **Wakeup correctness/perf.** `pick_job_from_work_queue` hands off a
surplus `notify_one` when work remains (parking_lot notifications are
not latched), and the enqueue-time `notify_one` re-wakes a parked helper
— the bootstrap wakeup the hand-off cannot provide from a fully-parked
state, which matters most on thread-limited runtimes.
- The `VecDeque` is presized to the job count so `push_back` never
reallocates under the queue lock.
Added a deterministic regression test
(`test_scope_worker_threads_occupied`): it pins every runtime worker
thread with a synchronous sleep, runs the scope on `spawn_blocking`, and
asserts it completes well before the sleep releases. This fails
(cleanly, via timeout) before the fix and passes after.
Closes NEXT-