fix: retry PipeServer::bind on stale pipe handles

PipeServer::bind was attempted once with no retry. A stale pipe handle
left over from a not-fully-cleaned-up previous instance causes
CreateNamedPipeW with FILE_FLAG_FIRST_PIPE_INSTANCE to fail with
ERROR_ACCESS_DENIED until the kernel releases the handle. The
single-instance forwarder thread was then never spawned and later
launches silently fell through to spawning a second app.

Retry up to 5 times with linear backoff (100ms-500ms) before giving up,
and log when retries are exhausted.

Closes #56
This commit is contained in:
Claude 2026-05-10 12:31:30 +00:00
parent bbbe882faf
commit e3401b61c1
No known key found for this signature in database

View file

@ -218,7 +218,16 @@ impl MainWindow {
}
}); // thread
if let Ok(mut listener) = PipeServer::bind(socket_path) {
// Retry: a stale FIRST_PIPE_INSTANCE handle returns ERROR_ACCESS_DENIED briefly.
let listener = (0..5).find_map(|attempt| match PipeServer::bind(socket_path) {
Ok(listener) => Some(listener),
Err(err) => {
eprintln!("PipeServer::bind failed (attempt {}): {err}", attempt + 1);
thread::sleep(time::Duration::from_millis(100 * (attempt + 1)));
None
}
});
if let Some(mut listener) = listener {
let focus_sender = self.focus_notice.sender();
thread::spawn(move || loop {
if let Ok(mut stream) = listener.accept() {
@ -232,6 +241,8 @@ impl MainWindow {
}
}
});
} else {
eprintln!("PipeServer::bind failed after retries; single-instance forwarding disabled");
}
// Read message from player