Skip to content

common: make no-task Waiter futex parking cancelable - #569

Merged
lalinsky merged 1 commit into
mainfrom
feat/waiter-cancelable-parking
Aug 20, 2026
Merged

common: make no-task Waiter futex parking cancelable#569
lalinsky merged 1 commit into
mainfrom
feat/waiter-cancelable-parking

Conversation

@lalinsky

Copy link
Copy Markdown
Owner

What

Makes the no-task (foreign/pool-thread) Waiter futex park respond to cancellation via the SIGURG cancel token, instead of silently absorbing the signal and re-parking.

Why

common.Waiter's no-task path went straight to a futex wait and only ever returned on completion — a .allow_cancel wait was effectively uncancelable. A SIGURG sent to a bound worker's token was swallowed as a spurious wakeup and the thread re-parked. This blocks any cancellation of blocking-thread parking (sleep/await/futex on a pool worker), which the blocking std.Io direction needs (issue #567).

How

waitFutex/timedWaitFutex, under .allow_cancel, now wrap the park in a syscall_cancel.Syscall region: SIGURG interrupts the futex with EINTR, and checkCancel turns a pending cancel into error.Canceled. The token is reached through the threadlocal that Token.enter binds, so nothing has to be threaded through the Waiter.

Zero impact on existing code: when no token is bound, Syscall.begin() yields a null-token no-op and the park is byte-for-byte the old behavior. Cancellation only activates when a bound token is canceled. .no_cancel always takes the plain path.

Test

A bare worker thread binds a Token, parks a never-signaled Waiter with .allow_cancel; the main thread cancel()s and resends SIGURG until acknowledged — the park returns error.Canceled in ~0.5ms (would hang without the fix).

All tests pass, zig fmt clean.

Note

This is the enabling half. It's a no-op until a token is actually bound on the parking thread — which the follow-up (blocking-task cancellation) does by giving AnyBlockingTask a token.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e3c1600f-998e-400f-b8ae-b49c32c185ad

📥 Commits

Reviewing files that changed from the base of the PR and between 99f20a7 and b16e8bc.

📒 Files selected for processing (1)
  • src/common.zig

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

Changes

Waiter no-task futex waits now receive cancel_mode. Cancelable waits use syscall cancellation checks and return error.Canceled. Timed waits return error.Timeout. The change adds Closeable and tests for timeout and cancellation behavior.

Changes

Futex wait behavior

Layer / File(s) Summary
Waiter wait contracts
src/common.zig
Waiter passes cancel_mode into regular and timed futex fallbacks. The public Closeable error set and syscall_cancel binding are added.
Cancelable and timed futex paths
src/common.zig
Cancelable waits use syscall regions and cancellation checks. Timed waits distinguish signals from timeout expiration and return error.Timeout.
Futex wait validation
src/common.zig
Tests verify explicit timeout behavior and cancellation of a worker parked on an unsignaled futex.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to b16e8

The change localizes cancellation handling for no-task waiter parking, with no actionable merge-blocking risk remaining based on the supplied evidence.

Possibly related PRs

Poem

Futex waits pause in place,
Cancellation changes pace.
Deadlines now report timeout,
Signals wake the waiter out.
Errors mark the path ahead.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: making no-task Waiter futex parking cancelable.
Description check ✅ Passed The description directly explains the cancellation problem, implementation, behavior, and test coverage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/waiter-cancelable-parking

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The no-task (foreign/pool-thread) `Waiter` park went straight to a futex
wait and only ever returned on completion — a `.allow_cancel` wait was
silently uncancelable. Cancellation (SIGURG on the worker's bound token)
was absorbed as a spurious wakeup and the thread re-parked.

Wrap the `.allow_cancel` futex park in a `syscall_cancel.Syscall` region:
SIGURG interrupts the futex with EINTR, and `checkCancel` turns a pending
cancel into `error.Canceled`. The token is reached through the threadlocal
that `Token.enter` binds, so nothing has to be threaded through the Waiter.

When no token is bound (a foreign thread with no cancellation source),
`begin()` yields a null-token no-op and the park behaves exactly as before,
so existing callers are unaffected. `.no_cancel` always takes the plain
path. Enables cancellation of blocking-thread parking (sleep/await/futex on
a pool worker) for the blocking std.Io direction (issue #567).
@lalinsky
lalinsky force-pushed the feat/waiter-cancelable-parking branch from 99f20a7 to b16e8bc Compare August 20, 2026 06:13
@lalinsky
lalinsky merged commit 7aac310 into main Aug 20, 2026
31 checks passed
@lalinsky
lalinsky deleted the feat/waiter-cancelable-parking branch August 20, 2026 06:29
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.

1 participant