From 98c7ca2c9f04bec1b7fe3c09b3d445f35b89ebd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sat, 22 Nov 2025 15:43:08 +0100 Subject: [PATCH] daemon: fix hang on SSH disconnect during remote builds When an SSH connection dies during a remote build, MonitorFdHup correctly detects the disconnect and calls triggerInterrupt(). However, without ReceiveInterrupts instantiated, no SIGUSR1 is sent to interrupt the blocking read() syscall. This causes the daemon to hang indefinitely while holding file locks, blocking subsequent builds. The fix instantiates ReceiveInterrupts in processConnection(), which registers a callback to send SIGUSR1 to the current thread when triggerInterrupt() is called. This allows the blocking read() to return with EINTR, causing checkInterrupt() to throw and the daemon to exit cleanly. This pattern is already used in ThreadPool::doWork() and SubstitutionGoal for the same purpose. --- src/libstore/daemon.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 937946134..1042c2412 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -1025,6 +1025,7 @@ void processConnection(ref store, FdSource && from, FdSink && to, Trusted #ifndef _WIN32 // TODO need graceful async exit support on Windows? auto monitor = !recursive ? std::make_unique(from.fd) : nullptr; (void) monitor; // suppress warning + ReceiveInterrupts receiveInterrupts; #endif /* Exchange the greeting. */