diff --git a/tensorrt_llm/_torch/pyexecutor/py_executor.py b/tensorrt_llm/_torch/pyexecutor/py_executor.py index 6cf98b759f02..78642af31d28 100644 --- a/tensorrt_llm/_torch/pyexecutor/py_executor.py +++ b/tensorrt_llm/_torch/pyexecutor/py_executor.py @@ -4947,8 +4947,13 @@ def _fetch_and_enqueue_requests(self, waiting_queue: WaitingQueue, if len(self.control_requests) != 0: return - # Calculate timeout - idle = (total_num_active_requests == 0) and len(waiting_queue) == 0 + # Calculate timeout. Never wait once the shutdown sentinel has been + # consumed: no further item will arrive to wake a blocking get(), so + # blocking would keep the loop from reaching the + # `should_stop_processing` check that ends it, deadlocking shutdown() + # on `shutdown_event`. + idle = (total_num_active_requests == 0 and len(waiting_queue) == 0 + and not self.is_shutdown) if idle: # In Ray path (TLLM_DISABLE_MPI=1), use a periodic heartbeat timeout so rank 0 # reaches the broadcast path regularly to prevent trtllm-serve timeout when idle.