use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
#[derive(Clone)]
pub struct SuspendHandler {
suspend_requested: Arc<AtomicBool>,
resumed: Arc<AtomicBool>,
}
impl SuspendHandler {
pub fn new() -> Self {
Self {
suspend_requested: Arc::new(AtomicBool::new(false)),
resumed: Arc::new(AtomicBool::new(false)),
}
}
pub fn request_suspend(&self) {
self.suspend_requested.store(true, Ordering::SeqCst);
}
pub fn take_suspend_request(&self) -> bool {
self.suspend_requested.swap(false, Ordering::SeqCst)
}
pub fn suspend_requested(&self) -> bool {
self.suspend_requested.load(Ordering::SeqCst)
}
pub fn mark_resumed(&self) {
self.resumed.store(true, Ordering::SeqCst);
}
pub fn take_resumed(&self) -> bool {
self.resumed.swap(false, Ordering::SeqCst)
}
}
impl Default for SuspendHandler {
fn default() -> Self {
Self::new()
}
}
#[cfg(unix)]
pub fn install_suspend_handlers(_handler: &SuspendHandler) -> std::io::Result<()> {
Ok(())
}
#[cfg(not(unix))]
pub fn install_suspend_handlers(_handler: &SuspendHandler) -> std::io::Result<()> {
Ok(())
}
#[cfg(unix)]
pub fn suspend_self() -> std::io::Result<()> {
unsafe {
let result = libc::raise(libc::SIGTSTP);
if result != 0 {
return Err(std::io::Error::last_os_error());
}
}
Ok(())
}
#[cfg(not(unix))]
pub fn suspend_self() -> std::io::Result<()> {
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_suspend_handler_creation() {
let handler = SuspendHandler::new();
assert!(!handler.suspend_requested());
}
#[test]
fn test_suspend_handler_request() {
let handler = SuspendHandler::new();
assert!(!handler.suspend_requested());
handler.request_suspend();
assert!(handler.suspend_requested());
assert!(handler.take_suspend_request());
assert!(!handler.suspend_requested());
}
#[test]
fn test_suspend_handler_resumed() {
let handler = SuspendHandler::new();
handler.mark_resumed();
assert!(handler.take_resumed());
assert!(!handler.take_resumed()); }
#[test]
fn test_suspend_handler_clone() {
let handler = SuspendHandler::new();
let handler2 = handler.clone();
handler.request_suspend();
assert!(handler2.suspend_requested());
}
}