Rust's std::sync::Mutex
is a struct that contains a heap-allocated inner
mutex, along with this semi-mysterious comment:
pub struct Mutex<T: ?Sized> {
// Note that this mutex is in a *box*, not inlined into the struct itself.
// Once a native mutex has been used once, its address can never change (it
// can't be moved). This mutex type can be safely moved at any time, so to
// ensure that the native mutex is used correctly we box the inner mutex to
// give it a constant address.
inner: Box<sys::Mutex>,
poison: poison::Flag,
data: UnsafeCell<T>,
}
The comment explains that Box
is used to give the inner mutex a stable address. But I can't seem to find any explanation for why a stable address is required in the first place.
On Unix-like platforms at least, the "native mutex" here (sys::Mutex
) is ultimately a wrapper around libc::pthread_mutex_t
(source code).
In C, it almost makes sense to have a rule against moving mutexes, because mutexes are used through pointers, and moving one while there is a live pointer to it would be clearly wrong. But in Rust, you can't even try to move something unless there are no live references to it. So this line of argument doesn't seem convincing.
Why must the native mutex have a stable address?