Fix process teardown deadlock on Windows (#55065)

AWS-LC registers an `atexit` handler that intentionally acquires a lock
without releasing it. AWS-LC also has `thread_local` objects which
acquire this lock in their destructor. Destructors for `thread_local`s
run under the loader lock. So, there is a race condition where, if a
thread exits after `atexit` handlers have run, the TLS destructors will
block indefinitely on this lock while holding the loader lock. Since
`ExitProcess` also requires the loader lock, process teardown will
deadlock.


Closes #54856

Release Notes:

- Fixed an issue where the Zed process wouldn't exit after closing all
windows
This commit is contained in:
John Tur authored and GitHub committed 2026-04-28 08:19:03 +00:00
1 parent 58d3c15483
commit 55adf85aa7
1 file changed
+11
+11
View File
@@ -410,6 +410,17 @@ impl Platform for WindowsPlatform {
self.inner
.with_callback(|callbacks| &callbacks.quit, |callback| callback());
// Bypass the CRT exit logic, which runs atexit handlers before calling ExitProcess.
// aws-lc registers an atexit handler that intentionally acquires a lock without releasing it.
// aws-lc also has thread_local objects which acquire this lock in their destructor.
// Destructors for thread_locals run under the loader lock, so there is a race condition
// where, if a thread exits after atexit handlers have run, the TLS destructors will block
// indefinitely on this lock while holding the loader lock. Since ExitProcess also requires
// the loader lock, process teardown will deadlock.
unsafe {
windows::Win32::System::Threading::ExitProcess(0);
}
}
fn quit(&self) {