atomic-bomb-engine 0.41.1

A high performance torture testing engine
Documentation
#[cfg(target_os = "windows")]
extern crate winapi;

use std::process::{Child, Command};

#[cfg(target_os = "windows")]
use winapi::um::winbase::SetThreadExecutionState;
#[cfg(target_os = "windows")]
use winapi::um::winnt::{ES_CONTINUOUS, ES_SYSTEM_REQUIRED};

pub(crate) struct SleepGuard {
    should_prevent: bool,
    #[cfg(not(target_os = "windows"))]
    process: Option<Child>,
}

impl SleepGuard {
    pub(crate) fn new(should_prevent: bool) -> Self {
        let mut guard = SleepGuard {
            should_prevent,
            #[cfg(not(target_os = "windows"))]
            process: None,
        };

        if should_prevent {
            guard.prevent_sleep();
        }

        guard
    }

    #[cfg(target_os = "windows")]
    fn prevent_sleep(&mut self) {
        unsafe {
            SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
        }
    }

    #[cfg(target_os = "macos")]
    fn prevent_sleep(&mut self) {
        let process = Command::new("caffeinate").spawn().ok();
        self.process = process;
    }

    #[cfg(target_os = "linux")]
    fn prevent_sleep(&mut self) {
        let process = Command::new("systemd-inhibit")
            .arg("--what=handle-lid-switch:sleep:idle")
            .arg("--who=RustApplication")
            .arg("--why=Prevent sleep for operation")
            .arg("--mode=block")
            .spawn()
            .ok();
        self.process = process;
    }
}

impl Drop for SleepGuard {
    fn drop(&mut self) {
        if self.should_prevent {
            #[cfg(target_os = "windows")]
            unsafe {
                SetThreadExecutionState(ES_CONTINUOUS);
            }

            #[cfg(not(target_os = "windows"))]
            if let Some(mut child) = self.process.take() {
                let _ = child.kill();
                let _ = child.wait();
            }
        }
    }
}