mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-02 06:27:53 -06:00
The GPU runner's workspace pool kept its free list and its count of made workspaces behind two mutexes, and forget() lowered the count without the free list's lock that a waiting caller holds. If the tiles in flight failed between a caller finding every workspace in use and that caller starting to wait, the wakeup was lost and the denoise thread blocked forever, out of reach of cancel. The free list and the count now share one lock in a small Workspaces type, so a give or a forget can't slip in between the check and the wait. A caller woken that way after the device was lost returns the GPU's error instead of making a new workspace on it.