mirror of
https://github.com/NotAShelf/stash.git
synced 2026-06-10 23:23:31 +00:00
clipboard: clear stale serving PID; fix persistence restart
Fixes #99 where persistence silently stops after the first entry because `SERVING_PID` was never reset in the parent after the child exited. Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Id41e16980c45e35be2a984e6f85b96e76a6a6964
This commit is contained in:
parent
3f2e34b8ea
commit
9120e57926
1 changed files with 29 additions and 1 deletions
|
|
@ -22,9 +22,25 @@ static SERVING_PID: AtomicI32 = AtomicI32::new(0);
|
|||
|
||||
/// Get the current serving PID if any. Used by the watch loop to avoid
|
||||
/// duplicate persistence processes.
|
||||
///
|
||||
/// Probes the stored PID with `kill(pid, 0)` to detect children that have
|
||||
/// already exited (SIGCHLD is ignored so we never get reaped notifications).
|
||||
/// A stale PID is cleared and `None` is returned.
|
||||
pub fn get_serving_pid() -> Option<i32> {
|
||||
let pid = SERVING_PID.load(Ordering::SeqCst);
|
||||
if pid != 0 { Some(pid) } else { None }
|
||||
if pid == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Signal 0 = existence check, no signal sent. Returns 0 if alive,
|
||||
// -1 (ESRCH) if the PID is gone.
|
||||
if unsafe { libc::kill(pid, 0) } == 0 {
|
||||
Some(pid)
|
||||
} else {
|
||||
let _ =
|
||||
SERVING_PID.compare_exchange(pid, 0, Ordering::SeqCst, Ordering::SeqCst);
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Result type for persistence operations.
|
||||
|
|
@ -157,6 +173,18 @@ unsafe fn fork_and_serve(prepared: PreparedCopy) -> PersistenceResult<()> {
|
|||
libc::signal(libc::SIGCHLD, libc::SIG_IGN);
|
||||
}
|
||||
|
||||
// Replace any prior serving child: a new clipboard entry supersedes the
|
||||
// old offer (the compositor will invalidate it anyway the moment the new
|
||||
// selection is taken). Without this, the old child lingers serving stale
|
||||
// data until MAX_SERVE_REQUESTS or invalidation.
|
||||
let prior = SERVING_PID.swap(0, Ordering::SeqCst);
|
||||
if prior > 0 && unsafe { libc::kill(prior, 0) } == 0 {
|
||||
unsafe {
|
||||
libc::kill(prior, libc::SIGTERM);
|
||||
}
|
||||
log::debug!("terminated prior persistence child (pid: {prior})");
|
||||
}
|
||||
|
||||
match unsafe { libc::fork() } {
|
||||
0 => {
|
||||
// Child process - clear serving PID
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue