about summary refs log tree commit diff
path: root/library/std/src/thread
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-03-27 21:46:58 +0000
committerbors <bors@rust-lang.org>2025-03-27 21:46:58 +0000
commit7586a9f99ad75287f9eef56c32c8508345ce0a73 (patch)
tree6c6a98e6deeb9e8633c4538e58f41f21fa8cdeb7 /library/std/src/thread
parent3f5502370b8f60e4df98deba4c22ea26f4f6be55 (diff)
parent6c2161a07c8f54e5b2838087a9a7406a789c98e8 (diff)
downloadrust-7586a9f99ad75287f9eef56c32c8508345ce0a73.tar.gz
rust-7586a9f99ad75287f9eef56c32c8508345ce0a73.zip
Auto merge of #138702 - m-ou-se:spawn-in-atexit, r=Mark-Simulacrum
Allow spawning threads after TLS destruction

Fixes #138696
Diffstat (limited to 'library/std/src/thread')
-rw-r--r--library/std/src/thread/spawnhook.rs23
1 files changed, 14 insertions, 9 deletions
diff --git a/library/std/src/thread/spawnhook.rs b/library/std/src/thread/spawnhook.rs
index 99b5ad9cb9f..98f471ad54b 100644
--- a/library/std/src/thread/spawnhook.rs
+++ b/library/std/src/thread/spawnhook.rs
@@ -113,18 +113,23 @@ where
 pub(super) fn run_spawn_hooks(thread: &Thread) -> ChildSpawnHooks {
     // Get a snapshot of the spawn hooks.
     // (Increments the refcount to the first node.)
-    let hooks = SPAWN_HOOKS.with(|hooks| {
+    if let Ok(hooks) = SPAWN_HOOKS.try_with(|hooks| {
         let snapshot = hooks.take();
         hooks.set(snapshot.clone());
         snapshot
-    });
-    // Iterate over the hooks, run them, and collect the results in a vector.
-    let to_run: Vec<_> = iter::successors(hooks.first.as_deref(), |hook| hook.next.as_deref())
-        .map(|hook| (hook.hook)(thread))
-        .collect();
-    // Pass on the snapshot of the hooks and the results to the new thread,
-    // which will then run SpawnHookResults::run().
-    ChildSpawnHooks { hooks, to_run }
+    }) {
+        // Iterate over the hooks, run them, and collect the results in a vector.
+        let to_run: Vec<_> = iter::successors(hooks.first.as_deref(), |hook| hook.next.as_deref())
+            .map(|hook| (hook.hook)(thread))
+            .collect();
+        // Pass on the snapshot of the hooks and the results to the new thread,
+        // which will then run SpawnHookResults::run().
+        ChildSpawnHooks { hooks, to_run }
+    } else {
+        // TLS has been destroyed. Skip running the hooks.
+        // See https://github.com/rust-lang/rust/issues/138696
+        ChildSpawnHooks::default()
+    }
 }
 
 /// The results of running the spawn hooks.