From 724078926e1d997c81461bb1b44bf22be8714b90 Mon Sep 17 00:00:00 2001 From: Codeman maintainer Date: Thu, 12 Nov 2026 02:43:34 +0100 Subject: [PATCH] test(desktop): the lid lock test waits for a lock that another test's process start keeps for a moment Seen on the Mac mini while checking the release tip: 1 failure in 21 runs of cargo test, at the line that takes the claim file right after its first holder dropped it (Busy instead of Yes). The lock is a flock, which lives as long as the last copy of the open file. The test binary runs its tests on threads, and a test that starts a process at that moment hands the new process a copy of every open file until its exec. Measured there with a throwaway stress test: with a second thread starting /usr/bin/true in a loop the lock was still held right after the drop in 12 of 28,000 rounds and free within 2 ms every time; with no process starts, 0 of 28,000. Test only. The app does not depend on the lock being free at once: the child asks for the file again every second, and nothing it holds is copied into another process, since it starts none. Co-Authored-By: Claude Fable 5.2 --- packages/desktop/src/lid_awake.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/desktop/src/lid_awake.rs b/packages/desktop/src/lid_awake.rs index a2a94cb8..96bcbbd2 100644 --- a/packages/desktop/src/lid_awake.rs +++ b/packages/desktop/src/lid_awake.rs @@ -925,7 +925,16 @@ mod system { ); // The holder dies without emptying it: the lock goes, the mark stays. drop(first); - assert_eq!(second.try_take(), Taken::Yes); + // Not always at once in a test run. Another test that starts a process at + // this moment hands it a copy of every open file of this one until its + // exec, and the lock lives as long as the last copy of the file. + let free = (0..400).any(|_| { + second.try_take() == Taken::Yes || { + std::thread::sleep(Duration::from_millis(5)); + false + } + }); + assert!(free, "the lock outlived its holder"); assert!(second.marked()); assert!(second.mark(false)); assert!(!second.marked());