Scoped thread implicit join completes before thread-locals are dropped #116179
Closed
Description
opened on Sep 26, 2023
When a scoped thread is implicitly joined, the destructors of thread-local variables are not guaranteed to have completed when the scope is exited. When a scoped thread is explicitly joined, however, the destructors of thread-local variables do complete before the scope is exited.
I tried this code:
use std::{hint::black_box, sync::Mutex, thread, time::Duration};
static MTX: Mutex<()> = Mutex::new(());
fn main() {
// Implicit join of scoped thread.
{
let lock = MTX.lock().unwrap();
thread::scope(|s| {
let _h = s.spawn(|| {
println!("on {:?}", thread::current().id());
FOO.with(|v| {
black_box(v);
});
});
});
println!("Executed 1st thread scope.");
drop(lock);
thread::sleep(Duration::from_millis(100));
}
// Explicit join of scoped thread.
{
let lock = MTX.lock().unwrap();
thread::scope(|s| {
let h = s.spawn(|| {
println!("on {:?}", thread::current().id());
FOO.with(|v| {
black_box(v);
});
});
h.join().unwrap();
});
println!("Executed 2nd thread scope.");
drop(lock);
thread::sleep(Duration::from_millis(100));
}
}
struct Foo(());
impl Drop for Foo {
fn drop(&mut self) {
println!("entering Foo::drop on {:?}", thread::current().id());
let _lock = MTX.lock().unwrap();
println!("Foo::drop completed on {:?}", thread::current().id());
}
}
thread_local! {
static FOO: Foo = Foo(());
}
I expected to see this happen: explanation
- The code would hang (deadlock) at the end of the first scoped thread block.
Instead, this happened: explanation
- The code does not hang (deadlock) at the end of the first scoped thread block.
- As expected, the code does hang (deadlock) at the end of the second scoped thread block, where the thread is joined explicitly..
Meta
The same behaviour is observed on the nightly version nightly-x86_64-unknown-linux-gnu unchanged - rustc 1.74.0-nightly (0288f2e19 2023-09-25)
.
rustc --version --verbose
:
rustc 1.72.1 (d5c2e9c34 2023-09-13)
binary: rustc
commit-hash: d5c2e9c342b358556da91d61ed4133f6f50fc0c3
commit-date: 2023-09-13
host: x86_64-unknown-linux-gnu
release: 1.72.1
LLVM version: 16.0.5
Backtrace
<backtrace>
Activity