1515
1616#[ derive( Debug , thiserror:: Error ) ]
1717pub enum SleepInhibitError {
18+ #[ cfg( target_os = "linux" ) ]
1819 #[ error( "D-Bus connection failed: {0}" ) ]
1920 DBusConnection ( #[ from] dbus:: Error ) ,
2021 #[ error( "Power management API failed: {0}" ) ]
@@ -96,6 +97,16 @@ mod linux_impl {
9697 _fd : OwnedFd ,
9798 }
9899
100+ /// See https://www.freedesktop.org/wiki/Software/systemd/inhibit/
101+ /// The Inhibit method takes four arguments:
102+ /// - what: "sleep" indicates we want to prevent sleep/suspend
103+ /// - who: The application name requesting the inhibition
104+ /// - why: Human-readable reason for the inhibition
105+ /// - mode: "block" completely blocks sleep, "delay" only delays it
106+ ///
107+ /// Returns a file descriptor that must be kept open to maintain the
108+ /// inhibition. The FD is closed automatically when this value is
109+ /// dropped.
99110 impl LinuxGuard {
100111 pub fn new ( app_name : & str , reason : & str ) -> Result < Self , SleepInhibitError > {
101112 let conn = Connection :: new_system ( ) . map_err ( SleepInhibitError :: DBusConnection ) ?;
@@ -125,15 +136,30 @@ mod linux_impl {
125136mod windows_impl {
126137 use super :: * ;
127138
139+ /// Informs the system that the state being set should remain in effect
140+ /// until the next call that uses ES_CONTINUOUS and one of the other
141+ /// state flags is cleared.
142+ const ES_CONTINUOUS : u32 = 0x80000000 ;
143+
144+ /// Forces the system to be in the working state by resetting the system
145+ /// idle timer.
146+ const ES_SYSTEM_REQUIRED : u32 = 0x00000001 ;
147+
128148 pub struct WindowsGuard ;
129149
150+ /// See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate
151+ /// SetThreadExecutionState modifies the system's sleep timer behavior.
152+ /// Parameters used:
153+ /// - ES_CONTINUOUS (0x80000000): State remains in effect until the next
154+ /// call
155+ /// - ES_SYSTEM_REQUIRED (0x00000001): Forces the system to stay in working
156+ /// state
157+ ///
158+ /// The system is automatically allowed to sleep again when this guard is
159+ /// dropped by clearing ES_SYSTEM_REQUIRED while maintaining
160+ /// ES_CONTINUOUS.
130161 impl WindowsGuard {
131162 pub fn new ( _app : & str , _reason : & str ) -> Result < Self , SleepInhibitError > {
132- // Map scope to execution state flags.
133- // ES_CONTINUOUS is always set to make the request sticky for this call.
134- const ES_CONTINUOUS : u32 = 0x80000000 ;
135- const ES_SYSTEM_REQUIRED : u32 = 0x00000001 ;
136-
137163 let flags: u32 = ES_CONTINUOUS | ES_SYSTEM_REQUIRED ;
138164
139165 // SAFETY: Calling documented Windows API with constant flags.
@@ -150,7 +176,6 @@ mod windows_impl {
150176 impl Drop for WindowsGuard {
151177 fn drop ( & mut self ) {
152178 // Clear the requirement and keep ES_CONTINUOUS.
153- const ES_CONTINUOUS : u32 = 0x80000000 ;
154179 // SAFETY: Restoring to a benign state.
155180 unsafe {
156181 windows_sys:: Win32 :: System :: Power :: SetThreadExecutionState ( ES_CONTINUOUS ) ;
@@ -191,9 +216,20 @@ mod mac_impl {
191216 id : IOPMAssertionID ,
192217 }
193218
219+ /// See https://developer.apple.com/documentation/iokit/1557134-IOPMAssertionCreateWithName
220+ /// IOPMAssertionCreateWithName creates a power assertion that prevents
221+ /// system sleep. Parameters:
222+ /// - assertion_type: "PreventSystemSleep" prevents the entire system from
223+ /// sleeping
224+ /// - level: 255 (kIOPMAssertionLevelOn) activates the assertion
225+ /// - assertion_name: A human-readable reason for the assertion
226+ /// - assertion_id: Returns an ID that must be released to remove the
227+ /// assertion
228+ ///
229+ /// The assertion is automatically released when this guard is dropped.
194230 impl MacGuard {
195231 pub fn new ( _app : & str , why : & str ) -> anyhow:: Result < Self > {
196- let assertion_type = "NoIdleSleepAssertion " ;
232+ let assertion_type = "PreventSystemSleep " ;
197233
198234 let mut id: IOPMAssertionID = 0 ;
199235 // SAFETY: FFI call with well-formed CFStrings that live across the call.
0 commit comments