julia
7a32ba2f - src: Deliver a pending ^C to scoped tasks without the listener

Commit
100 days ago
src: Deliver a pending ^C to scoped tasks without the listener The C side of ^C delivery marks the episode source directly, but a task running under a scoped child source (e.g. inside @sync) polls its own source at cancellation points - carrying the episode's cancellation down to it required the julia-side sigint listener's tree walk. In a single-threaded process (julia's default) whose only thread runs a compute-bound task, the listener never gets scheduled, so the first ^C never landed and only the escalation ladder could get through. The per-thread cancellation-delivery paths - which every ^C already triggers on every thread - now carry the pending episode into the interrupted task's bound source themselves: if the source is governed by the episode source (parent-chain membership), the episode's state byte is CAS-maxed into it, a single async-signal-safe write, and the task's next cancellation point observes it with no julia-side scheduling at all. The listener's eventual walk redoes the remaining bookkeeping level-triggered. Three gates had to open for this to work: the dispatch-pending flag is set before the per-thread sends (the handlers race it otherwise), and the senders no longer require a published interruptible-region context when a ^C dispatch is pending and the task carries a binding - a purely polling victim between cancellation points never has one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KLwCBAR64r3cTdfaC5krU
Author
Committer
Parents
Loading