fix: instant toggle exit via SIGUSR1 poll interruption

Remove SA_RESTART from the signal handler so SIGUSR1 interrupts the
blocking poll() call with EINTR. Handle EINTR gracefully in the event
loop to check should_exit() immediately instead of waiting for timeout.
This commit is contained in:
swaits committed 2026-04-07 12:28:42 -06:00
1 parent d73ba4af11
commit 421bd04339
2 files changed
+13 -2

No files matched your search

+3 -1
View File
@@ -73,9 +73,11 @@ pub fn create_lock() -> Result<LockGuard> {
let path = lock_file_path();
// Install SIGUSR1 handler before writing the lock file.
// No SA_RESTART — let the signal interrupt poll() so the event loop
// notices should_exit() promptly instead of waiting for the timeout.
let action = SigAction::new(
SigHandler::Handler(handle_sigusr1),
SaFlags::SA_RESTART,
SaFlags::empty(),
SigSet::empty(),
);
unsafe { signal::sigaction(Signal::SIGUSR1, &action) }.context("install SIGUSR1 handler")?;
+10 -1
View File
@@ -163,7 +163,16 @@ impl WaylandBackend {
let mut pollfd =
[nix::poll::PollFd::new(fd, nix::poll::PollFlags::POLLIN)];
let millis = timeout.as_millis().min(u16::MAX as u128) as u16;
let n = nix::poll::poll(&mut pollfd, millis).context("poll")?;
let n = match nix::poll::poll(&mut pollfd, millis) {
Ok(n) => n,
Err(nix::errno::Errno::EINTR) => {
// Signal interrupted poll — return so the loop
// can check should_exit().
drop(read_guard);
return Ok(None);
}
Err(e) => return Err(e).context("poll"),
};
if n > 0 {
let _ = read_guard.read();