Not sure if anything needs to be done about this, since I don't know of any actual implementations having a problem with it, but it occurred to me when thinking about moving mutexes.
On Unix, Mutex::new corresponds to initialization with PTHREAD_MUTEX_INITIALIZER; Mutex::lock, which returns a MutexGuard, corresponds to pthread_mutex_lock; MutexGuard::drop corresponds to pthread_mutex_unlock; and Mutex::drop corresponds to pthread_mutex_destroy.
If a MutexGuard is forgotten:
use std::sync::Mutex;
use std::mem::forget;
fn main() {
let mutex: Mutex<()> = Mutex::new(());
let guard = mutex.lock();
forget(guard);
}
...then we call pthread_mutex_destroy without first calling pthread_mutex_unlock. The POSIX spec says:
It shall be safe to destroy an initialized mutex that is unlocked. Attempting to destroy a locked mutex or a mutex that is referenced (for example, while being used in a pthread_cond_timedwait() or pthread_cond_wait()) by another thread results in undefined behavior.
Not sure if anything needs to be done about this, since I don't know of any actual implementations having a problem with it, but it occurred to me when thinking about moving mutexes.
On Unix,
Mutex::newcorresponds to initialization withPTHREAD_MUTEX_INITIALIZER;Mutex::lock, which returns aMutexGuard, corresponds topthread_mutex_lock;MutexGuard::dropcorresponds topthread_mutex_unlock; andMutex::dropcorresponds topthread_mutex_destroy.If a
MutexGuardis forgotten:...then we call
pthread_mutex_destroywithout first callingpthread_mutex_unlock. The POSIX spec says: