ReviewOS

zig-utils/zig-js

Threads: cancel queued starts during Context teardown

#1033
Closed chris opened this 9 days ago ·
9 days ago

Parent: #502 Related: #1032

Executed reproduction

On exact main at ddad1d5540e66f6db81b74d099740e8515d0f54f, a focused test creates an enable_threads Context, pauses the public runnable scheduler at zero, constructs a shared-realm JavaScript Thread through the production constructor, confirms its typed start is queued, and destroys the Context on its owner thread. A bounded observer shows teardown does not finish until runnable capacity is restored:

jsthread.test.Context teardown exits while a JavaScript Thread start is scheduler-paused...FAIL (TestUnexpectedResult)

Context teardown sets teardown_stop and interrupts runtime waiters, but a pre-entry runtime_threads.startThread cannot observe either. The teardown loop waits for ThreadRecord.exited, so the queued OS thread and Context wait on one another while the embedder's intentional zero-capacity policy remains in force.

Required change

  • Give each spawned shared-realm ThreadRecord the typed start-cancellation handle introduced by #1032.
  • During Context teardown, cancel only pre-entry starts before waiting for done/exited; concurrently granted or running Threads continue through the existing stop/checkpoint path.
  • A canceled start must release its active-interpreter reservation and microtask-transfer reservation, clear entry roots, publish coherent done/joins_settled/exited state, wake teardown, and leave exact scheduler/thread/stack accounting balanced.
  • Do not raise scheduler capacity, execute the entry callable outside a slot, discard a running Thread, poll/sleep as the implementation, or weaken normal join/asyncJoin semantics.

Definition of done

  • The zero-capacity Context teardown reproduction finishes before capacity is restored.
  • The canceled entry callable does not run; interpreter and microtask reservations return to their pre-spawn values.
  • Deterministic grant/cancel and GIL/no-GIL teardown tests preserve completion and queue invariants.
  • Normal and unsuppressed-TSan focused gates pass with zero leaks.
  • #502 is updated with the landed commit and evidence.
9 days ago

Landed on main in f26b968.

Context teardown now cancels shared-realm JavaScript Thread starts that are still waiting for their initial scheduler slot. The bounded zero-capacity reproduction finishes without restoring capacity, the entry callable remains unexecuted, constructor reservations return exactly to their baseline, and running starts retain the existing stop/checkpoint path.

Validation:

  • focused normal tests: pass
  • focused unsuppressed TSan tests: pass
  • full unit suite: 2,573 passed; 1 skipped; 0 failed; 0 leaked
  • zig build -j1: pass
  • zig build runtime-thread-audit: pass (6 production sites, 152 test-only spawns)
  • docs link check: 378 files pass
  • test262 flips: not measured because the pinned corpus is unavailable in this checkout

Sign in to comment on this issue.