Skip to content

linux system adapter: InstallShutdownHook for SIGTERM/SIGINT - #128

Merged
turinglambdaai merged 1 commit into
mainfrom
feat/linux-shutdown-hook
Oct 8, 2026
Merged

turinglambdaai merged 1 commit into
mainfrom
feat/linux-shutdown-hook

Conversation

@turinglambdaai

@turinglambdaai turinglambdaai commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

First Linux adapter slice of #120.

The embedded Racket CS runtime installs its own signal handlers, so a staged Linux host can absorb SIGTERM: state flushing on container stops, session shutdown, and kill <pid> is then bypassed.

rivet::system::InstallShutdownHook(callback) gives hosts one safe opt-in shutdown boundary:

  • the signal handler performs only a non-blocking one-byte self-pipe write and preserves errno;
  • the read end remains blocking, so the detached watcher cannot mistake EAGAIN for shutdown;
  • the watcher restores default SIGTERM/SIGINT handling before running the callback on a normal stack, then uses _Exit to avoid static-destruction races;
  • a second signal exits immediately if a callback hangs;
  • pipe2(O_CLOEXEC) and checked fcntl setup prevent descriptor inheritance and signal-handler deadlock;
  • partial installation failures restore prior signal dispositions and close both descriptors;
  • installing twice throws, matching InstallCrashHook.

The Linux embedded-roundtrip workflow now launches a real probe process, proves it stays alive before SIGTERM, verifies the callback marker, and requires a clean zero-status exit within five seconds.

Hosts still opt in by calling the hook early on the main thread. Scaffold wiring and the macOS/Windows equivalents remain follow-up work, so #120 stays open.

@turinglambdaai
turinglambdaai force-pushed the feat/linux-shutdown-hook branch 3 times, most recently from f6e43da to 2f6208a Compare October 8, 2026 02:06
First-party shutdown plumbing for #120: embedded Racket CS installs its
own signal handlers, so a staged host absorbs SIGTERM and exit-time
state flushing never runs on OS logout, launchd kills, or plain
`kill <pid>`.

InstallShutdownHook(callback) installs a SIGTERM/SIGINT handler that is
async-signal-safe (one write into a self-pipe); a watcher thread runs
the callback on a normal stack — file writes and other state flushing
are allowed there — and exits with status 0. A second signal restores
the default disposition so operators can still hard-kill a stuck
shutdown. pipe2(O_CLOEXEC) with a non-blocking read end; falls back to
pipe()+fcntl where pipe2 is unavailable.

macOS/WinRT get the equivalent surfaces in follow-ups; the pattern
matches RivetSystem's crash-hook contract.
@turinglambdaai
turinglambdaai force-pushed the feat/linux-shutdown-hook branch from 2f6208a to b7ac6c2 Compare October 8, 2026 07:05
@turinglambdaai
turinglambdaai merged commit 5fff7d7 into main Oct 8, 2026
15 checks passed
@turinglambdaai
turinglambdaai deleted the feat/linux-shutdown-hook branch October 8, 2026 07:21
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