diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-06-25 15:14:09 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-25 15:14:09 +0200 |
| commit | ecefccd8d2859c6715760861c7dacfcdf816992a (patch) | |
| tree | 85e8c78d6b37d2c1be7f2bce20c05fe7280cae87 /library/std/src/sys | |
| parent | 45ef23d78e54ff2d12db78c6445f766f61972c86 (diff) | |
| parent | e642c5987e1885a6ea9b0f1527810a72bdcdeb3f (diff) | |
| download | rust-ecefccd8d2859c6715760861c7dacfcdf816992a.tar.gz rust-ecefccd8d2859c6715760861c7dacfcdf816992a.zip | |
Rollup merge of #98194 - m-ou-se:leak-locked-pthread-mutex, r=Amanieu
Leak pthread_{mutex,rwlock}_t if it's dropped while locked.
Fixes https://github.com/rust-lang/rust/issues/85434.
Diffstat (limited to 'library/std/src/sys')
| -rw-r--r-- | library/std/src/sys/unix/locks/pthread_mutex.rs | 20 | ||||
| -rw-r--r-- | library/std/src/sys/unix/locks/pthread_rwlock.rs | 16 |
2 files changed, 35 insertions, 1 deletions
diff --git a/library/std/src/sys/unix/locks/pthread_mutex.rs b/library/std/src/sys/unix/locks/pthread_mutex.rs index 916e898d890..98afee69ba6 100644 --- a/library/std/src/sys/unix/locks/pthread_mutex.rs +++ b/library/std/src/sys/unix/locks/pthread_mutex.rs @@ -1,5 +1,5 @@ use crate::cell::UnsafeCell; -use crate::mem::MaybeUninit; +use crate::mem::{forget, MaybeUninit}; use crate::sys::cvt_nz; use crate::sys_common::lazy_box::{LazyBox, LazyInit}; @@ -23,6 +23,24 @@ impl LazyInit for Mutex { unsafe { mutex.init() }; mutex } + + fn destroy(mutex: Box<Self>) { + // We're not allowed to pthread_mutex_destroy a locked mutex, + // so check first if it's unlocked. + if unsafe { mutex.try_lock() } { + unsafe { mutex.unlock() }; + drop(mutex); + } else { + // The mutex is locked. This happens if a MutexGuard is leaked. + // In this case, we just leak the Mutex too. + forget(mutex); + } + } + + fn cancel_init(_: Box<Self>) { + // In this case, we can just drop it without any checks, + // since it cannot have been locked yet. + } } impl Mutex { diff --git a/library/std/src/sys/unix/locks/pthread_rwlock.rs b/library/std/src/sys/unix/locks/pthread_rwlock.rs index 75e5759c787..adfe2a88338 100644 --- a/library/std/src/sys/unix/locks/pthread_rwlock.rs +++ b/library/std/src/sys/unix/locks/pthread_rwlock.rs @@ -1,4 +1,5 @@ use crate::cell::UnsafeCell; +use crate::mem::forget; use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sys_common::lazy_box::{LazyBox, LazyInit}; @@ -17,6 +18,21 @@ impl LazyInit for RwLock { fn init() -> Box<Self> { Box::new(Self::new()) } + + fn destroy(mut rwlock: Box<Self>) { + // We're not allowed to pthread_rwlock_destroy a locked rwlock, + // so check first if it's unlocked. + if *rwlock.write_locked.get_mut() || *rwlock.num_readers.get_mut() != 0 { + // The rwlock is locked. This happens if a RwLock{Read,Write}Guard is leaked. + // In this case, we just leak the RwLock too. + forget(rwlock); + } + } + + fn cancel_init(_: Box<Self>) { + // In this case, we can just drop it without any checks, + // since it cannot have been locked yet. + } } impl RwLock { |
