Skip to content

fix: make timers and signals safe against re-entrant continuations and lost signals - #15191

Open
algebraic-dev wants to merge 12 commits into
sofia/libuv-socket-fixesfrom
sofia/libuv-timer-signal-fixes
Open

algebraic-dev wants to merge 12 commits into
sofia/libuv-socket-fixesfrom
sofia/libuv-timer-signal-fixes

Conversation

@algebraic-dev

Copy link
Copy Markdown
Member

This PR fixes crashes in libuv timers and signals:

  • One shot timer and signal callbacks resolved their promise before releasing the event loop's reference to the handle (sync := true) caused this.
  • libuv treats a repeat period of 0 as a oneshot timer, so a repeating Timer with a 0 ms period fired once and every later promise stayed pending. It now ticks every millisecond.
  • Signal.cancel only drops the pending promise and keeps the handler listening, and a signal that arrives with no promise pending resolves the promise of the next next.
  • Signal waiters resolve with the number from Signal.toInt32 on every platform, instead of the operating system's number for that signal.

algebraic-dev and others added 12 commits September 15, 2026 19:21
…ntinuations

This PR fixes use-after-free crashes when a (sync := true) continuation of a timer or signal promise cancels or stops the handle, marks timer promises multi-threaded, restores timer state when starting fails, and no longer asserts when the caller resolved the promise itself.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This PR makes a repeating libuv timer created with a 0 ms period keep ticking every millisecond instead of firing only once.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This PR makes Signal.Waiter.selector report a waiter that already received its signal as ready.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This PR corrects the libuv timer, signal and socket documentation to match their current behavior.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… numbers

A signal selector that loses a select no longer misses a signal delivered before the next select, and selecting on a `Sleep` no longer cancels it, so it keeps its deadline across selects. Signal waiters now resolve with the signal number in Lean's `Signal` numbering instead of the operating system's, and a `Sleep` or `Interval` longer than a `UInt64` of milliseconds is clamped instead of wrapping to a short duration.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`Signal.cancel` now only drops the pending promise and keeps the handler listening, and a signal that arrives with no promise pending is reported by the next `next` instead of being consumed. `Signal.Waiter.selector` goes back to cancelling on unregister, without the extra state it kept to avoid losing those signals.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A `Sleep` whose selector loses a select is cancelled again, so the next select starts it from its full duration; the documentation of `Sleep.selector` now says so. This drops the separate `Selector.sleep` override that stopped one-off timers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…-fixes

# Conflicts:
#	src/Std/Internal/UV/UDP.lean
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@algebraic-dev algebraic-dev self-assigned this Sep 17, 2026
@github-actions github-actions Bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Sep 17, 2026
@algebraic-dev algebraic-dev added the awaiting-author Waiting for PR author to address issues label Sep 22, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-author Waiting for PR author to address issues changelog-library Library toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant