Description
The current documentation of JoinHandle::join
doesn't specify the effect of joining the thread on the atomics that the thread modified. I couldn't find any other place in the documentation where this would be described either.
Without additional guarantees, the call to AtomicUsize::into_inner
in the following snippet could be understood to constitute a data race:
let i_ref = Arc::new(AtomicUsize::new(0));
let thr = std::thread::spawn({
let i_ref = i_ref.clone();
move || i_ref.store(1, Ordering:: Relaxed)
});
thr.join().unwrap();
let i = Arc::try_unwrap(i_ref).unwrap().into_inner();
assert_eq!(i, 1);
In comparison, cppreference explicitly states that "The completion of the thread identified by *this
synchronizes with the corresponding successful return from join()
."
The nomicon does claim that Rust just inherits C11's memory model for atomics, which could be used to infer that JoinHandle::join
has the same effect as C++'s std::thread::join
. It would still be a good idea to document the synchronizes-with relation explicitly to avoid confusion such as in this stackoverflow question.