@@ -2417,78 +2417,62 @@ fn log_status(label: &str, pid: u32, status: &io::Result<ExitStatus>) {
24172417 }
24182418}
24192419
2420- struct StopCommandConfig < ' a > {
2421- max_followup : Duration ,
2422- label_graceful : & ' a str ,
2423- label_force : & ' a str ,
2424- subject : & ' a str ,
2425- }
2426-
2427- fn stop_child_process_impl (
2428- child : & mut Child ,
2429- timeout : Duration ,
2430- graceful_cmd : impl FnOnce ( & str ) -> Command ,
2431- force_cmd : impl FnOnce ( & str ) -> Command ,
2432- config : StopCommandConfig < ' _ > ,
2433- ) -> bool {
2420+ /// Attempt to stop a child process gracefully within `timeout`.
2421+ ///
2422+ /// On the force-kill path, a follow-up wait is derived from `timeout` (`timeout / 4`)
2423+ /// and capped per-platform:
2424+ /// - Windows: up to 2200ms.
2425+ /// - Non-Windows: up to 1500ms.
2426+ #[ cfg( target_os = "windows" ) ]
2427+ fn stop_child_process_gracefully ( child : & mut Child , timeout : Duration ) -> bool {
24342428 let pid = child. id ( ) ;
24352429 let pid_arg = pid. to_string ( ) ;
24362430
2437- let graceful_status = graceful_cmd ( pid_arg. as_str ( ) ) . status ( ) ;
2438- log_status ( config . label_graceful , pid, & graceful_status) ;
2431+ let graceful_status = build_stop_command ( "taskkill" , & [ "/pid" , & pid_arg, "/t" ] ) . status ( ) ;
2432+ log_status ( "taskkill graceful stop" , pid, & graceful_status) ;
24392433
24402434 if wait_for_child_exit ( child, timeout) {
24412435 return true ;
24422436 }
24432437
2444- let force_status = force_cmd ( pid_arg. as_str ( ) ) . status ( ) ;
2445- log_status ( config . label_force , pid, & force_status) ;
2438+ let force_status = build_stop_command ( "taskkill" , & [ "/pid" , & pid_arg, "/t" , "/f" ] ) . status ( ) ;
2439+ log_status ( "taskkill force stop" , pid, & force_status) ;
24462440
2447- let followup_wait = derive_force_stop_wait ( timeout, config. max_followup ) ;
2441+ let followup_wait = derive_force_stop_wait (
2442+ timeout,
2443+ Duration :: from_millis ( FORCE_STOP_WAIT_MAX_WINDOWS_MS ) ,
2444+ ) ;
24482445 append_desktop_log ( & format ! (
2449- "{} graceful stop timed out, force-kill issued: pid={pid}, graceful={graceful_status:?}, force={force_status:?}, followup_wait_ms={}" ,
2450- config. subject,
2446+ "child graceful stop timed out, force-kill issued: pid={pid}, graceful={graceful_status:?}, force={force_status:?}, followup_wait_ms={}" ,
24512447 followup_wait. as_millis( ) ,
24522448 ) ) ;
24532449 wait_for_child_exit ( child, followup_wait)
24542450}
24552451
2456- /// Attempt to stop a child process gracefully within `timeout`.
2457- ///
2458- /// On the force-kill path, a follow-up wait is derived from `timeout` (`timeout / 4`)
2459- /// and capped per-platform:
2460- /// - Windows: up to 2200ms.
2461- /// - Non-Windows: up to 1500ms.
2462- #[ cfg( target_os = "windows" ) ]
2463- fn stop_child_process_gracefully ( child : & mut Child , timeout : Duration ) -> bool {
2464- stop_child_process_impl (
2465- child,
2466- timeout,
2467- |pid_arg| build_stop_command ( "taskkill" , & [ "/pid" , pid_arg, "/t" ] ) ,
2468- |pid_arg| build_stop_command ( "taskkill" , & [ "/pid" , pid_arg, "/t" , "/f" ] ) ,
2469- StopCommandConfig {
2470- max_followup : Duration :: from_millis ( FORCE_STOP_WAIT_MAX_WINDOWS_MS ) ,
2471- label_graceful : "taskkill graceful stop" ,
2472- label_force : "taskkill force stop" ,
2473- subject : "child" ,
2474- } ,
2475- )
2476- }
2477-
24782452#[ cfg( not( target_os = "windows" ) ) ]
24792453fn stop_child_process_gracefully ( child : & mut Child , timeout : Duration ) -> bool {
2480- stop_child_process_impl (
2481- child,
2454+ let pid = child. id ( ) ;
2455+ let pid_arg = pid. to_string ( ) ;
2456+
2457+ let graceful_status = build_stop_command ( "kill" , & [ "-TERM" , & pid_arg] ) . status ( ) ;
2458+ log_status ( "kill -TERM" , pid, & graceful_status) ;
2459+
2460+ if wait_for_child_exit ( child, timeout) {
2461+ return true ;
2462+ }
2463+
2464+ let force_status = build_stop_command ( "kill" , & [ "-KILL" , & pid_arg] ) . status ( ) ;
2465+ log_status ( "kill -KILL" , pid, & force_status) ;
2466+
2467+ let followup_wait = derive_force_stop_wait (
24822468 timeout,
2483- |pid_arg| build_stop_command ( "kill" , & [ "-TERM" , pid_arg] ) ,
2484- |pid_arg| build_stop_command ( "kill" , & [ "-KILL" , pid_arg] ) ,
2485- StopCommandConfig {
2486- max_followup : Duration :: from_millis ( FORCE_STOP_WAIT_MAX_NON_WINDOWS_MS ) ,
2487- label_graceful : "kill -TERM" ,
2488- label_force : "kill -KILL" ,
2489- subject : "child" ,
2490- } ,
2491- )
2469+ Duration :: from_millis ( FORCE_STOP_WAIT_MAX_NON_WINDOWS_MS ) ,
2470+ ) ;
2471+ append_desktop_log ( & format ! (
2472+ "child graceful stop timed out, force-kill issued: pid={pid}, graceful={graceful_status:?}, force={force_status:?}, followup_wait_ms={}" ,
2473+ followup_wait. as_millis( ) ,
2474+ ) ) ;
2475+ wait_for_child_exit ( child, followup_wait)
24922476}
24932477
24942478fn build_debug_command ( plan : & LaunchPlan ) -> Vec < String > {
0 commit comments