Skip to content

windows/macos: orderly embedded-backend shutdown on session end - #171

Merged
turinglambdaai merged 5 commits into
mainfrom
windows-macos-graceful-shutdown
Oct 9, 2026
Merged

turinglambdaai merged 5 commits into
mainfrom
windows-macos-graceful-shutdown

Conversation

@turinglambdaai

Copy link
Copy Markdown
Owner

Fixes #120 (completes the Windows/macOS half; Linux landed via #128 + #168).

Change

  • Windows adapter: InstallShutdownHook(std::function<void()>) over SetConsoleCtrlHandler — CTRL_C/CTRL_CLOSE/CTRL_LOGOFF/CTRL_SHUTDOWN (session logoff and OS shutdown reach GUI processes through the logoff/shutdown events even without a console). Mirrors the Linux adapter's name and synchronous, allocation-light callback contract.
  • Windows scaffold: Window.Closed and the hook both funnel into StopBackendOrderly() — std::atomic_load of the backend shared_ptr + thread-safe stop(); the control thread never touches XAML state. Hook installation failure degrades to the window-close path only.
  • macOS scaffold: @NSApplicationDelegateAdaptor + applicationShouldTerminate → registered backend stop(), covering Cmd-Q, window close, logout, and OS shutdown.

Verification

  • Freshly scaffolded app compiled on Windows (MSVC 0 errors) with the new wiring.
  • tests/codegen.rkt pins the scaffold contract (hook present in the Windows template source, StopBackendOrderly declared, applicationShouldTerminate/orderlyShutdown in the macOS template).
  • Full suite: 8745 tests passed; macOS/Windows packaging smoke and the Swift runtime build gate run in CI.

ren.ji added 5 commits October 9, 2026 23:29
The Linux adapter has shipped InstallShutdownHook since #128 and the
scaffold wires it since #168; Windows and macOS scaffolds had no signal
or session-end path, so logoff/shutdown killed the process with the
backend mid-flight.

- Windows system adapter: InstallShutdownHook over SetConsoleCtrlHandler
  (CTRL_C_EVENT, CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, CTRL_SHUTDOWN_
  EVENT — session logoff and OS shutdown reach GUI processes through the
  last two). Registration failure throws; the callback contract stays
  synchronous and allocation-light like the Linux hook.
- Windows scaffold: MainWindow funnels window close (Window.Closed) and
  the console-control callback into StopBackendOrderly, which reads the
  shared backend through std::atomic_load and calls the thread-safe
  stop() — the control callback runs on its own thread and never touches
  XAML state.
- macOS scaffold: NSApplicationDelegateAdaptor with
  applicationShouldTerminate runs the registered backend stop for every
  termination path (Cmd-Q, window close, logout, shutdown).

Fixes #120.
Swift strict concurrency rejects a nonisolated static var; AppKit delivers
applicationShouldTerminate on the main thread, so MainActor plus
assumeIsolated keeps registration (from the MainActor AppModel) and the
callback on one isolation domain.
@turinglambdaai
turinglambdaai merged commit d1e25e7 into main Oct 9, 2026
15 checks passed
@turinglambdaai
turinglambdaai deleted the windows-macos-graceful-shutdown branch October 9, 2026 20: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.

Embedded runtime ignores SIGTERM: graceful shutdown hooks never run on signals/logout

1 participant