From cb3f80301012296f655457ac27b8c0eb97971c13 Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Thu, 5 Mar 2026 00:47:35 +0900 Subject: [PATCH] Stop non-main threads during interpreter finalization Raise SystemExit in check_signals() for non-main threads once the finalizing flag is set. Without GIL, this serves as the checkpoint where daemon threads detect shutdown, analogous to CPython's _PyThreadState_MustExit in take_gil. --- crates/vm/src/vm/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/vm/src/vm/mod.rs b/crates/vm/src/vm/mod.rs index ef65bf59d65..eb1c37ed2f7 100644 --- a/crates/vm/src/vm/mod.rs +++ b/crates/vm/src/vm/mod.rs @@ -1479,6 +1479,13 @@ impl VirtualMachine { /// Checks for triggered signals and calls the appropriate handlers. A no-op on /// platforms where signals are not supported. pub fn check_signals(&self) -> PyResult<()> { + #[cfg(feature = "threading")] + if self.state.finalizing.load(Ordering::Acquire) && !self.is_main_thread() { + // once finalization starts, + // non-main Python threads should stop running bytecode. + return Err(self.new_exception(self.ctx.exceptions.system_exit.to_owned(), vec![])); + } + #[cfg(not(target_arch = "wasm32"))] { crate::signal::check_signals(self)