Every backend spawned by the Windows desktop shell hung forever in the
startup worker's `import torch`, inside the loader for numpy's OpenBLAS
DLL. The desktop parent-liveness watchdog (0a20aeb0) parks a synchronous
read on the stdin pipe the shell hands the backend, and that pending read
deadlocks the DLL initializer. The identical command from a terminal, with
no stdin pipe and no watchdog, starts in seconds — which is why it only
reproduced under the app.
Bisected outside the app by spawning the backend with the shell's exact
env, pipes, creation flags and job object: a watchdog thread that merely
sleeps is harmless; a pending ReadFile, via the C runtime or straight to
the kernel, hangs it every time. Native stacks (py-spy --native) show the
watchdog in NtReadFile and the importer waiting on a critical section from
inside the OpenBLAS initializer.
Fix: on Windows the watchdog polls PeekNamedPipe and reads only bytes that
are already buffered, so no I/O is ever outstanding on the pipe. It still
exits the instant the desktop closes its end (ERROR_BROKEN_PIPE), and a
non-pipe stdin keeps the shared blocking reader. Verified: the app-style
spawn goes from an indefinite hang to ready in ~3 s, and the desktop-prod
build boots and loads the model.
Not in v0.5.1; the watchdog landed 2026-08-30 on main.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HCDZcBpP6QQa4dzUa8z6rh