Skip to content

libstd Mutex can cause POSIX undefined behavior #31936

@comex

Description

@comex

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions