Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7586a9f

Browse files
committed
Auto merge of #138702 - m-ou-se:spawn-in-atexit, r=Mark-Simulacrum
Allow spawning threads after TLS destruction Fixes #138696
2 parents 3f55023 + 6c2161a commit 7586a9f

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

‎library/std/src/thread/spawnhook.rs‎

Lines changed: 14 additions & 9 deletions
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+
iflet 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.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Regression test for https://github.com/rust-lang/rust/issues/138696
2+
//@ only-unix
3+
//@ needs-threads
4+
//@ run-pass
5+
6+
#![feature(rustc_private)]
7+
8+
extern crate libc;
9+
10+
fn main() {
11+
std::thread::spawn(|| {
12+
unsafe { libc::atexit(spawn_in_atexit) };
13+
})
14+
.join()
15+
.unwrap();
16+
}
17+
18+
extern "C" fn spawn_in_atexit() {
19+
std::thread::spawn(|| {
20+
println!("Thread spawned in atexit");
21+
})
22+
.join()
23+
.unwrap();
24+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /