Skip to content

Commit a6e0dd2

Browse files
committed
Auto merge of rust-lang#138702 - m-ou-se:spawn-in-atexit, r=Mark-Simulacrum
Allow spawning threads after TLS destruction Fixes rust-lang#138696
2 parents 71da267 + b2f2bbd commit a6e0dd2

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

std/src/thread/spawnhook.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -113,18 +113,23 @@ where
113113
pub(super) fn run_spawn_hooks(thread: &Thread) -> ChildSpawnHooks {
114114
// Get a snapshot of the spawn hooks.
115115
// (Increments the refcount to the first node.)
116-
let hooks = SPAWN_HOOKS.with(|hooks| {
116+
if let Ok(hooks) = SPAWN_HOOKS.try_with(|hooks| {
117117
let snapshot = hooks.take();
118118
hooks.set(snapshot.clone());
119119
snapshot
120-
});
121-
// Iterate over the hooks, run them, and collect the results in a vector.
122-
let to_run: Vec<_> = iter::successors(hooks.first.as_deref(), |hook| hook.next.as_deref())
123-
.map(|hook| (hook.hook)(thread))
124-
.collect();
125-
// Pass on the snapshot of the hooks and the results to the new thread,
126-
// which will then run SpawnHookResults::run().
127-
ChildSpawnHooks { hooks, to_run }
120+
}) {
121+
// Iterate over the hooks, run them, and collect the results in a vector.
122+
let to_run: Vec<_> = iter::successors(hooks.first.as_deref(), |hook| hook.next.as_deref())
123+
.map(|hook| (hook.hook)(thread))
124+
.collect();
125+
// Pass on the snapshot of the hooks and the results to the new thread,
126+
// which will then run SpawnHookResults::run().
127+
ChildSpawnHooks { hooks, to_run }
128+
} else {
129+
// TLS has been destroyed. Skip running the hooks.
130+
// See https://github.com/rust-lang/rust/issues/138696
131+
ChildSpawnHooks::default()
132+
}
128133
}
129134

130135
/// The results of running the spawn hooks.

0 commit comments

Comments
 (0)