Skip to content

task core: port wait_until's pending-cancel wakeup; clear Thread.cancellable on resume (review, closes #250) - #302

Merged
lannbot merged 1 commit into
mainfrom
fix/review-wait-until-cancel
Sep 7, 2026
Merged

task core: port wait_until's pending-cancel wakeup; clear Thread.cancellable on resume (review, closes #250)#302
lannbot merged 1 commit into
mainfrom
fix/review-wait-until-cancel

Conversation

@lannbot

@lannbot lannbot commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Adversarial correctness review of main @ 396a216, task-core track. One HIGH and one LOW finding in Thread/Task, pinned by regression tests that fail on the pre-fix tree.

F1 (HIGH) — lost wakeup in Thread.waitUntil. The reference (Thread.wait_until, definitions.py 361-373) parks on ready_func() or (cancellable() and has_pending_cancel()) and re-runs deliver_pending_cancel AFTER the block. Ours parked on the raw readyFunc and checked only before. When a cancel arrives while a sibling holds the instance's exclusive slot (request parks as pending-cancel), the reference wakes the parked callback task on slot release and delivers TASK_CANCELLED; ours left the WAIT arm parked until an unrelated event (possibly forever — the canceller got BLOCKED and waits for a SUBTASK event that never comes), returned a spurious NONE on the YIELD arm, and delivered a pending event ahead of TASK_CANCELLED. wait_until_pending_cancel_test.ts pins all three arms.

This is CM#707 item 2(c) of #250. async/cancel-and-exclusive-lock.wast:196 now passes; its xfail — the last of class cm707-cancel — is removed, and the eight engine-lane expectation files and the README total move 1284→1285 passed / 127→126 xfail.

F2 (LOW) — stale Thread.cancellable. Stayed true while the thread ran, so a requestCancellation reaching a RUNNING implicit thread hit Thread.resume's assertion instead of parking as pending-cancel. Cleared on resume. stale_cancellable_flag_test.ts.

Gates: just test-runtime green; just conformance 0 failed / 0 stale; just sched-seeds green; all six browser lanes and three shell lanes match the updated expectations; full just gates green on the union of the five review PRs.

Closes #250. Follow-up for the JSPI SuspensionPoint twin of this path: #300.

Automerge armed.

…ellable on resume

Adversarial correctness review of the task core against definitions.py.

`Thread.waitUntil` parked on the raw `readyFunc` and checked
`deliverPendingCancel` only BEFORE blocking. The reference (`Thread.wait_until`
361-373) parks on `ready_func() or (cancellable() and has_pending_cancel())`
and re-runs `deliver_pending_cancel` AFTER the block. The gap bites when a
cancel arrives while the task is not cancellable — a sibling activation of
the instance holds the exclusive slot, so `Task.requestCancellation` parks
the request as `pending-cancel`. When the slot frees, the reference wakes
the parked callback task and hands it TASK_CANCELLED; ours left the WAIT arm
parked until some unrelated event landed on its set (possibly never: the
canceller got BLOCKED and waits for a SUBTASK event that never comes),
delivered a spurious NONE on the YIELD arm, and reordered a pending event
ahead of TASK_CANCELLED. The reference's `cancellable` is a live predicate
(`lock_available` in the callback loop, 2167/2175); ours is a static flag per
block point, so the "lock is free" conjunct is supplied by the new
`Task.implicitThreadCancellable()`, which also replaces the inline
`excludeImplicit` expression in `requestCancellation`.

`Thread.cancellable` stayed stale-true while the thread ran, so a
`requestCancellation` reaching a RUNNING implicit thread (a nested same-
instance task cancelling a handle whose callee is on the stack) picked it
and hit `Thread.resume`'s assertion instead of parking as pending-cancel.
Cleared on resume; re-set by the next block request.

This is CM#707 item 2(c) of #250 — "deliver when the callee's exclusive lock
frees, even if the parked task's waitable set never fires".
`async/cancel-and-exclusive-lock.wast:196` now passes; its xfail (the last
of class `cm707-cancel`) is removed.

Regression: wait_until_pending_cancel_test.ts (three arms),
stale_cancellable_flag_test.ts. Conformance 0 failed / 0 stale; sched-seeds
green.

Closes #250.
@lannbot
lannbot enabled auto-merge September 7, 2026 02:12
@lannbot
lannbot merged commit f79ff11 into main Sep 7, 2026
4 checks passed
@lannbot
lannbot deleted the fix/review-wait-until-cancel branch September 7, 2026 02:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

adopt CM#705/#707 cancellation delivery: subtask.cancel rewrite + pending-cancel ASAP bookkeeping

2 participants