mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Summary - simplify the macOS sleep inhibitor FFI by replacing `dlopen` / `dlsym` / `transmute` with normal IOKit extern calls and `SAFETY` comments - switch to cfg-selected platform implementations (`imp::SleepInhibitor`) instead of `Box<dyn ...>` - check in minimal IOKit bindings generated with `bindgen` and include them from the macOS backend - enable direct IOKit linkage in Bazel macOS builds by registering `IOKit` in the Bazel `osx.framework(...)` toolchain extension list - update `Cargo.lock` and `MODULE.bazel.lock` after removing the build-time `bindgen` dependency path Testing - `just fmt` - `cargo clippy -p codex-utils-sleep-inhibitor --all-targets -- -D warnings` - `cargo test -p codex-utils-sleep-inhibitor` - `bazel test //codex-rs/utils/sleep-inhibitor:all --test_output=errors` - `just bazel-lock-update` - `just bazel-lock-check` Context - follow-up to #11711 addressing Ryan's review comments - `bindgen` is used to generate the checked-in bindings file, but not at build time
90 lines
2.3 KiB
Rust
90 lines
2.3 KiB
Rust
//! Cross-platform helper for preventing idle sleep while a turn is running.
|
|
//!
|
|
//! On macOS this uses native IOKit power assertions instead of spawning
|
|
//! `caffeinate`, so assertion lifecycle is tied directly to Rust object lifetime.
|
|
|
|
#[cfg(not(target_os = "macos"))]
|
|
mod dummy;
|
|
#[cfg(target_os = "macos")]
|
|
mod macos;
|
|
|
|
#[cfg(not(target_os = "macos"))]
|
|
use dummy as imp;
|
|
#[cfg(target_os = "macos")]
|
|
use macos as imp;
|
|
|
|
/// Keeps the machine awake while a turn is in progress when enabled.
|
|
#[derive(Debug)]
|
|
pub struct SleepInhibitor {
|
|
enabled: bool,
|
|
platform: imp::SleepInhibitor,
|
|
}
|
|
|
|
impl SleepInhibitor {
|
|
pub fn new(enabled: bool) -> Self {
|
|
Self {
|
|
enabled,
|
|
platform: imp::SleepInhibitor::new(),
|
|
}
|
|
}
|
|
|
|
/// Update the active turn state; turns sleep prevention on/off as needed.
|
|
pub fn set_turn_running(&mut self, turn_running: bool) {
|
|
if !self.enabled {
|
|
self.release();
|
|
return;
|
|
}
|
|
|
|
if turn_running {
|
|
self.acquire();
|
|
} else {
|
|
self.release();
|
|
}
|
|
}
|
|
|
|
fn acquire(&mut self) {
|
|
self.platform.acquire();
|
|
}
|
|
|
|
fn release(&mut self) {
|
|
self.platform.release();
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::SleepInhibitor;
|
|
|
|
#[test]
|
|
fn sleep_inhibitor_toggles_without_panicking() {
|
|
let mut inhibitor = SleepInhibitor::new(true);
|
|
inhibitor.set_turn_running(true);
|
|
inhibitor.set_turn_running(false);
|
|
}
|
|
|
|
#[test]
|
|
fn sleep_inhibitor_disabled_does_not_panic() {
|
|
let mut inhibitor = SleepInhibitor::new(false);
|
|
inhibitor.set_turn_running(true);
|
|
inhibitor.set_turn_running(false);
|
|
}
|
|
|
|
#[test]
|
|
fn sleep_inhibitor_multiple_true_calls_are_idempotent() {
|
|
let mut inhibitor = SleepInhibitor::new(true);
|
|
inhibitor.set_turn_running(true);
|
|
inhibitor.set_turn_running(true);
|
|
inhibitor.set_turn_running(true);
|
|
inhibitor.set_turn_running(false);
|
|
}
|
|
|
|
#[test]
|
|
fn sleep_inhibitor_can_toggle_multiple_times() {
|
|
let mut inhibitor = SleepInhibitor::new(true);
|
|
inhibitor.set_turn_running(true);
|
|
inhibitor.set_turn_running(false);
|
|
inhibitor.set_turn_running(true);
|
|
inhibitor.set_turn_running(false);
|
|
}
|
|
}
|