@@ -352,11 +352,13 @@ fn run_lifecycle_monitor_with_bus<W: Write, E: SessionActionExecutor>(
352352 ) ?;
353353
354354 let mut sleep_inhibitor = None ;
355- acquire_lifecycle_sleep_delay_inhibitor_if_enabled (
355+ let mut waiting_for_resume = false ;
356+ sync_lifecycle_sleep_delay_inhibitor_if_idle (
356357 writer,
357358 bus,
358359 config_path,
359360 & mut sleep_inhibitor,
361+ waiting_for_resume,
360362 ) ?;
361363
362364 let started = Instant :: now ( ) ;
@@ -378,6 +380,14 @@ fn run_lifecycle_monitor_with_bus<W: Write, E: SessionActionExecutor>(
378380 . min ( timeout. saturating_sub ( started. elapsed ( ) ) ) ;
379381 }
380382
383+ sync_lifecycle_sleep_delay_inhibitor_if_idle (
384+ writer,
385+ bus,
386+ config_path,
387+ & mut sleep_inhibitor,
388+ waiting_for_resume,
389+ ) ?;
390+
381391 let Some ( signal) =
382392 bus. process ( process_timeout)
383393 . map_err ( |err| SessionRunnerError :: Failed {
@@ -393,6 +403,12 @@ fn run_lifecycle_monitor_with_bus<W: Write, E: SessionActionExecutor>(
393403 } ;
394404
395405 let event_kind = LifecycleEvent :: from_runtime_event ( event) ;
406+ match event_kind {
407+ Some ( LifecycleEvent :: MachinePreparingForSleep ) => waiting_for_resume = true ,
408+ Some ( LifecycleEvent :: MachineResumed ) => waiting_for_resume = false ,
409+ _ => { }
410+ }
411+
396412 if !lifecycle_policy_enabled_from_config ( config_path) ? {
397413 release_lifecycle_sleep_delay_inhibitor ( writer, & mut sleep_inhibitor) ?;
398414 writeln ! (
@@ -409,11 +425,12 @@ fn run_lifecycle_monitor_with_bus<W: Write, E: SessionActionExecutor>(
409425 match event_kind {
410426 Some ( LifecycleEvent :: MachineResumed ) => {
411427 dispatcher. dispatch_lifecycle_event ( writer, event) ?;
412- acquire_lifecycle_sleep_delay_inhibitor_if_enabled (
428+ sync_lifecycle_sleep_delay_inhibitor_if_idle (
413429 writer,
414430 bus,
415431 config_path,
416432 & mut sleep_inhibitor,
433+ waiting_for_resume,
417434 ) ?;
418435 }
419436 Some ( LifecycleEvent :: MachinePreparingForSleep ) => {
@@ -436,13 +453,19 @@ fn run_lifecycle_monitor_with_bus<W: Write, E: SessionActionExecutor>(
436453 }
437454}
438455
439- fn acquire_lifecycle_sleep_delay_inhibitor_if_enabled < W : Write > (
456+ fn sync_lifecycle_sleep_delay_inhibitor_if_idle < W : Write > (
440457 writer : & mut W ,
441458 bus : & mut impl SessionBusClient ,
442459 config_path : & Path ,
443460 sleep_inhibitor : & mut Option < OwnedFd > ,
461+ waiting_for_resume : bool ,
444462) -> Result < ( ) , SessionRunnerError > {
445- if sleep_inhibitor. is_some ( ) || !lifecycle_policy_enabled_from_config ( config_path) ? {
463+ if !lifecycle_policy_enabled_from_config ( config_path) ? {
464+ release_lifecycle_sleep_delay_inhibitor ( writer, sleep_inhibitor) ?;
465+ return Ok ( ( ) ) ;
466+ }
467+
468+ if waiting_for_resume || sleep_inhibitor. is_some ( ) {
446469 return Ok ( ( ) ) ;
447470 }
448471
@@ -1572,6 +1595,7 @@ mod tests {
15721595 method_calls : Vec < ( String , String , String , String ) > ,
15731596 inhibitor_write_fds : Vec < i32 > ,
15741597 disable_config_after_signals : Option < PathBuf > ,
1598+ enable_config_after_idle : Option < PathBuf > ,
15751599 }
15761600
15771601 impl SessionBusClient for FakeSessionBus {
@@ -1636,6 +1660,9 @@ mod tests {
16361660 if let Some ( config_path) = self . disable_config_after_signals . take ( ) {
16371661 write_lifecycle_config ( & config_path, "disabled" ) ;
16381662 }
1663+ if let Some ( config_path) = self . enable_config_after_idle . take ( ) {
1664+ write_lifecycle_config ( & config_path, "enabled" ) ;
1665+ }
16391666
16401667 Ok ( None )
16411668 }
@@ -1806,6 +1833,7 @@ system_sleep_wake_policy={policy}
18061833 method_calls : Vec :: new ( ) ,
18071834 inhibitor_write_fds : Vec :: new ( ) ,
18081835 disable_config_after_signals : Some ( config_path. clone ( ) ) ,
1836+ enable_config_after_idle : None ,
18091837 } ;
18101838 let mut output = Vec :: new ( ) ;
18111839
@@ -1854,6 +1882,7 @@ system_sleep_wake_policy={policy}
18541882 method_calls : Vec :: new ( ) ,
18551883 inhibitor_write_fds : Vec :: new ( ) ,
18561884 disable_config_after_signals : None ,
1885+ enable_config_after_idle : None ,
18571886 } ;
18581887 let mut output = Vec :: new ( ) ;
18591888
@@ -1871,6 +1900,45 @@ system_sleep_wake_policy={policy}
18711900 std:: env:: remove_var ( super :: LIFECYCLE_MONITOR_TEST_EVENT_LIMIT_ENV ) ;
18721901 }
18731902
1903+ #[ test]
1904+ fn lifecycle_monitor_reacquires_inhibitor_when_policy_is_reenabled_while_idle ( ) {
1905+ let _guard = env_lock ( )
1906+ . lock ( )
1907+ . unwrap_or_else ( |poisoned| poisoned. into_inner ( ) ) ;
1908+ std:: env:: set_var ( super :: LIFECYCLE_MONITOR_TEST_TIMEOUT_SECS_ENV , "0.2" ) ;
1909+
1910+ let config_path = unique_config_path ( "lifecycle-reenabled" ) ;
1911+ write_lifecycle_config ( & config_path, "disabled" ) ;
1912+ let executor = FakeActionExecutor :: default ( ) ;
1913+ let mut bus = FakeLifecycleBus {
1914+ signals : VecDeque :: new ( ) ,
1915+ signal_match_count : 0 ,
1916+ method_calls : Vec :: new ( ) ,
1917+ inhibitor_write_fds : Vec :: new ( ) ,
1918+ disable_config_after_signals : None ,
1919+ enable_config_after_idle : Some ( config_path. clone ( ) ) ,
1920+ } ;
1921+ let mut output = Vec :: new ( ) ;
1922+
1923+ run_lifecycle_monitor_with_bus ( & mut output, executor, & config_path, & mut bus)
1924+ . expect ( "lifecycle loop exits cleanly after test timeout" ) ;
1925+
1926+ let output = String :: from_utf8 ( output) . expect ( "utf8" ) ;
1927+ assert ! ( output. contains( "Using logind system lifecycle source" ) ) ;
1928+ assert ! ( output. contains( "Acquired logind sleep delay inhibitor" ) ) ;
1929+ assert_eq ! ( bus. signal_match_count, 1 ) ;
1930+ assert_eq ! (
1931+ bus. method_calls
1932+ . iter( )
1933+ . map( |( _, _, _, member) | member. as_str( ) )
1934+ . collect:: <Vec <_>>( ) ,
1935+ vec![ "Inhibit" ]
1936+ ) ;
1937+ assert ! ( bus. enable_config_after_idle. is_none( ) ) ;
1938+ fs:: remove_file ( config_path) . expect ( "remove lifecycle test config" ) ;
1939+ std:: env:: remove_var ( super :: LIFECYCLE_MONITOR_TEST_TIMEOUT_SECS_ENV ) ;
1940+ }
1941+
18741942 #[ test]
18751943 fn unhandled_events_are_logged_without_running_actions ( ) {
18761944 let executor = FakeActionExecutor :: default ( ) ;
0 commit comments