mirror of
https://github.com/openai/codex.git
synced 2026-04-24 14:45:27 +00:00
Refine Linux and Windows sleep inhibitor robustness
This commit is contained in:
2
codex-rs/Cargo.lock
generated
2
codex-rs/Cargo.lock
generated
@@ -2505,7 +2505,7 @@ dependencies = [
|
||||
"core-foundation 0.9.4",
|
||||
"libc",
|
||||
"tracing",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -17,7 +17,7 @@ tracing = { workspace = true }
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
tracing = { workspace = true }
|
||||
windows-sys = { version = "0.60.2", features = [
|
||||
windows-sys = { version = "0.52", features = [
|
||||
"Win32_Foundation",
|
||||
"Win32_System_Power",
|
||||
"Win32_System_SystemServices",
|
||||
|
||||
@@ -5,11 +5,15 @@ use tracing::warn;
|
||||
|
||||
const ASSERTION_REASON: &str = "Codex is running an active turn";
|
||||
const APP_ID: &str = "codex";
|
||||
// Keep the blocker process alive "long enough" without needing restarts.
|
||||
// This is `i32::MAX` seconds, which is accepted by common `sleep` implementations.
|
||||
const BLOCKER_SLEEP_SECONDS: &str = "2147483647";
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct LinuxSleepInhibitor {
|
||||
state: InhibitState,
|
||||
preferred_backend: Option<LinuxBackend>,
|
||||
missing_backend_logged: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@@ -36,34 +40,87 @@ impl LinuxSleepInhibitor {
|
||||
|
||||
impl PlatformSleepInhibitor for LinuxSleepInhibitor {
|
||||
fn acquire(&mut self) {
|
||||
if let InhibitState::Active { child, .. } = &mut self.state
|
||||
&& child.try_wait().ok().flatten().is_none()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.state = InhibitState::Inactive;
|
||||
|
||||
for backend in [
|
||||
LinuxBackend::SystemdInhibit,
|
||||
LinuxBackend::GnomeSessionInhibit,
|
||||
] {
|
||||
match spawn_backend(backend) {
|
||||
Ok(child) => {
|
||||
self.state = InhibitState::Active { backend, child };
|
||||
return;
|
||||
if let InhibitState::Active { backend, child } = &mut self.state {
|
||||
match child.try_wait() {
|
||||
Ok(None) => return,
|
||||
Ok(Some(status)) => {
|
||||
warn!(
|
||||
?backend,
|
||||
?status,
|
||||
"Linux sleep inhibitor backend exited unexpectedly; attempting fallback"
|
||||
);
|
||||
}
|
||||
Err(error) => {
|
||||
warn!(
|
||||
?backend,
|
||||
reason = %error,
|
||||
"Failed to start Linux sleep inhibitor backend"
|
||||
"Failed to query Linux sleep inhibitor backend status"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
warn!("No Linux sleep inhibitor backend is available");
|
||||
self.state = InhibitState::Inactive;
|
||||
let should_log_backend_failures = !self.missing_backend_logged;
|
||||
let backends = match self.preferred_backend {
|
||||
Some(LinuxBackend::SystemdInhibit) => [
|
||||
LinuxBackend::SystemdInhibit,
|
||||
LinuxBackend::GnomeSessionInhibit,
|
||||
],
|
||||
Some(LinuxBackend::GnomeSessionInhibit) => [
|
||||
LinuxBackend::GnomeSessionInhibit,
|
||||
LinuxBackend::SystemdInhibit,
|
||||
],
|
||||
None => [
|
||||
LinuxBackend::SystemdInhibit,
|
||||
LinuxBackend::GnomeSessionInhibit,
|
||||
],
|
||||
};
|
||||
|
||||
for backend in backends {
|
||||
match spawn_backend(backend) {
|
||||
Ok(mut child) => match child.try_wait() {
|
||||
Ok(None) => {
|
||||
self.state = InhibitState::Active { backend, child };
|
||||
self.preferred_backend = Some(backend);
|
||||
self.missing_backend_logged = false;
|
||||
return;
|
||||
}
|
||||
Ok(Some(status)) => {
|
||||
if should_log_backend_failures {
|
||||
warn!(
|
||||
?backend,
|
||||
?status,
|
||||
"Linux sleep inhibitor backend exited immediately"
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(error) => {
|
||||
if should_log_backend_failures {
|
||||
warn!(
|
||||
?backend,
|
||||
reason = %error,
|
||||
"Failed to query Linux sleep inhibitor backend status after spawn"
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(error) => {
|
||||
if should_log_backend_failures && error.kind() != std::io::ErrorKind::NotFound {
|
||||
warn!(
|
||||
?backend,
|
||||
reason = %error,
|
||||
"Failed to start Linux sleep inhibitor backend"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if should_log_backend_failures {
|
||||
warn!("No Linux sleep inhibitor backend is available");
|
||||
self.missing_backend_logged = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn release(&mut self) {
|
||||
|
||||
@@ -39,7 +39,7 @@ impl PlatformSleepInhibitor for WindowsSleepInhibitor {
|
||||
}
|
||||
Err(error) => {
|
||||
warn!(
|
||||
reason = error,
|
||||
reason = %error,
|
||||
"Failed to acquire Windows sleep-prevention request"
|
||||
);
|
||||
}
|
||||
@@ -58,7 +58,7 @@ struct PowerRequest {
|
||||
}
|
||||
|
||||
impl PowerRequest {
|
||||
fn new_execution_required(reason: &str) -> Result<Self, &'static str> {
|
||||
fn new_execution_required(reason: &str) -> Result<Self, String> {
|
||||
let mut wide_reason: Vec<u16> = OsStr::new(reason).encode_wide().chain(once(0)).collect();
|
||||
let context = REASON_CONTEXT {
|
||||
Version: POWER_REQUEST_CONTEXT_VERSION,
|
||||
@@ -69,13 +69,15 @@ impl PowerRequest {
|
||||
};
|
||||
let handle = unsafe { PowerCreateRequest(&context) };
|
||||
if handle.is_null() {
|
||||
return Err("PowerCreateRequest failed");
|
||||
let error = std::io::Error::last_os_error();
|
||||
return Err(format!("PowerCreateRequest failed: {error}"));
|
||||
}
|
||||
|
||||
let request_type = PowerRequestExecutionRequired;
|
||||
if unsafe { PowerSetRequest(handle, request_type) } == 0 {
|
||||
let error = std::io::Error::last_os_error();
|
||||
let _ = unsafe { CloseHandle(handle) };
|
||||
return Err("PowerSetRequest failed");
|
||||
return Err(format!("PowerSetRequest failed: {error}"));
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
|
||||
Reference in New Issue
Block a user