diff --git a/local/recipes/system/redbear-sessiond/source/src/acpi_watcher.rs b/local/recipes/system/redbear-sessiond/source/src/acpi_watcher.rs index 3803c52c65..4a3bd67e90 100644 --- a/local/recipes/system/redbear-sessiond/source/src/acpi_watcher.rs +++ b/local/recipes/system/redbear-sessiond/source/src/acpi_watcher.rs @@ -3,17 +3,50 @@ use zbus::Connection; use crate::runtime_state::SharedRuntime; #[cfg(target_os = "redox")] -const KSTOP_PATH: &str = "/scheme/kernel.acpi/kstop"; +mod redox_shutdown { + /// Block until the kernel signals a shutdown. + /// + /// Phase B of the ACPI fork-sync replaced the `/scheme/kernel.acpi/kstop` + /// file with a single Fd-based call() interface. The kstop sub-handle + /// is event-driven (see kernel/scheme/acpi.rs register_kstop). + /// + /// Rather than subscribing to the event queue (which would require + /// pulling in `redox_event` and dealing with the macro-deprecation + /// churn), we poll the `AcpiVerb::CheckShutdown` kcall every 250ms. + /// This is the supported pattern for userspace that just wants + /// the boolean "is shutdown pending" signal. + pub fn wait_for_shutdown_edge() -> std::io::Result<()> { + let parent = libredox::Fd::open( + "/scheme/kernel.acpi", + libredox::flag::O_CLOEXEC, + 0, + )?; + // Open the kstop sub-handle. The kernel requires us to call + // CheckShutdown on the kstop handle (HandleBits::KSTOP_HANDLE), + // not on the parent handle. + let kstop = parent.openat("kstop", libredox::flag::O_CLOEXEC, 0)?; + + // AcpiVerb::CheckShutdown = 2. + loop { + let mut buf = [0u8; 8]; + let n = kstop.call_ro( + &mut buf, + redox_syscall::flag::CallFlags::empty(), + &[2u64], + )?; + if n > 0 { + let shutdown = u64::from_le_bytes(buf[..8].try_into().unwrap_or([0; 8])); + if shutdown != 0 { + return Ok(()); + } + } + std::thread::sleep(std::time::Duration::from_millis(250)); + } + } +} #[cfg(target_os = "redox")] -fn wait_for_shutdown_edge() -> std::io::Result<()> { - use std::io::Read; - - let mut file = std::fs::File::open(KSTOP_PATH)?; - let mut byte = [0_u8; 1]; - let _ = file.read(&mut byte)?; - Ok(()) -} +use redox_shutdown::wait_for_shutdown_edge; pub async fn watch_and_emit(connection: Connection, runtime: SharedRuntime) { #[cfg(target_os = "redox")] @@ -45,4 +78,4 @@ pub async fn watch_and_emit(connection: Connection, runtime: SharedRuntime) { let _ = connection; let _ = runtime; } -} +} \ No newline at end of file diff --git a/local/sources/base b/local/sources/base index de9d1f495f..8140a2cd27 160000 --- a/local/sources/base +++ b/local/sources/base @@ -1 +1 @@ -Subproject commit de9d1f495f0444aeb93e10407e0c76514c9bde14 +Subproject commit 8140a2cd2753d8b85d536068bf4a79b8a5a7e961 diff --git a/local/sources/kernel b/local/sources/kernel index 4cb9d80396..4f2a0436eb 160000 --- a/local/sources/kernel +++ b/local/sources/kernel @@ -1 +1 @@ -Subproject commit 4cb9d80396f727bacff1dc41fefaa2df18197a8b +Subproject commit 4f2a0436eb98863e400496557fb529d447ff66e2