@@ -84,15 +84,15 @@ impl WorkerState {
8484 Some ( Ok ( ( worker_task_id, worker_result) ) ) => {
8585 let process_state = self
8686 . worker_map
87- . swap_remove ( & worker_task_id)
87+ . shift_remove ( & worker_task_id)
8888 . expect ( "worker task ID not found" ) ;
8989 ( process_state. worker_id , worker_result)
9090 }
9191 Some ( Err ( e) ) => {
9292 let worker_task_id = e. id ( ) ;
9393 let process_state = self
9494 . worker_map
95- . swap_remove ( & worker_task_id)
95+ . shift_remove ( & worker_task_id)
9696 . expect ( "worker task ID not found" ) ;
9797 let e = if e. is_cancelled ( ) {
9898 ProcessError :: Aborted
@@ -163,6 +163,7 @@ impl WorkerState {
163163
164164 // Wait for the process to exit by driving the `JoinSet`. If other workers complete while we're waiting,
165165 // we'll simply remove them from the worker map and continue waiting.
166+ let mut aborted = false ;
166167 loop {
167168 select ! {
168169 worker_result = self . worker_tasks. join_next_with_id( ) => {
@@ -173,7 +174,7 @@ impl WorkerState {
173174 break ;
174175 } else {
175176 debug!( ?worker_task_id, "Non-target process exited successfully. Continuing to wait." ) ;
176- let removed = self . worker_map. swap_remove ( & worker_task_id) ;
177+ let removed = self . worker_map. shift_remove ( & worker_task_id) ;
177178 debug_assert!( removed. is_some( ) , "non-target worker must be in the worker map" ) ;
178179 }
179180 } ,
@@ -184,17 +185,20 @@ impl WorkerState {
184185 break ;
185186 } else {
186187 debug!( ?worker_task_id, "Non-target process exited with error. Continuing to wait." ) ;
187- let removed = self . worker_map. swap_remove ( & worker_task_id) ;
188+ let removed = self . worker_map. shift_remove ( & worker_task_id) ;
188189 debug_assert!( removed. is_some( ) , "non-target worker must be in the worker map" ) ;
189190 }
190191 }
191192 None => unreachable!( "worker task must exist in join set if we are waiting for it" ) ,
192193 }
193194 } ,
194- // We've exceeded the shutdown timeout, so we need to abort the process.
195- _ = & mut shutdown_deadline => {
195+ // We've exceeded the shutdown timeout, so we abort the process. The `if !aborted` guard stops this
196+ // arm from re-firing on every poll once the deadline has elapsed (an elapsed `Sleep` stays ready),
197+ // which would otherwise spin re-aborting until the task is reaped.
198+ _ = & mut shutdown_deadline, if !aborted => {
196199 debug!( worker_id, "Shutdown timeout expired, forcefully aborting process." ) ;
197200 abort_handle. abort( ) ;
201+ aborted = true ;
198202 }
199203 }
200204 }
0 commit comments