Rollup merge of #77147 - fusion-engineering-forks:static-mutex, r=dtolnay
Split sys_common::Mutex in StaticMutex and MovableMutex. The (unsafe) `Mutex` from `sys_common` had a rather complicated interface. You were supposed to call `init()` manually, unless you could guarantee it was neither moved nor used reentrantly. Calling `destroy()` was also optional, although it was unclear if 1) resources might be leaked or not, and 2) if `destroy()` should only be called when `init()` was called. This allowed for a number of interesting (confusing?) different ways to use this `Mutex`, all captured in a single type. In practice, this type was only ever used in two ways: 1. As a static variable. In this case, neither `init()` nor `destroy()` are called. The variable is never moved, and it is never used reentrantly. It is only ever locked using the `LockGuard`, never with `raw_lock`. 2. As a `Box`ed variable. In this case, both `init()` and `destroy()` are called, it will be moved and possibly used reentrantly. No other combinations are used anywhere in `std`. This change simplifies things by splitting this `Mutex` type into two types matching the two use cases: `StaticMutex` and `MovableMutex`. The interface of both new types is now both safer and simpler. The first one does not call nor expose `init`/`destroy`, and the second one calls those automatically in its `new()` and `Drop` functions. Also, the locking functions of `MovableMutex` are no longer unsafe. --- This will also make it easier to conditionally box mutexes later, by moving that decision into sys/sys_common. Some of the mutex implementations (at least those of Wasm and 'sys/unsupported') are safe to move, so wouldn't need a box. ~~(But that's blocked on #76932 for now.)~~ (See #77380.)
This commit is contained in:
commit
1c4a5f8d1e
15 changed files with 116 additions and 145 deletions
|
@ -80,13 +80,13 @@ mod imp {
|
|||
use crate::ptr;
|
||||
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
|
||||
|
||||
use crate::sys_common::mutex::Mutex;
|
||||
use crate::sys_common::mutex::StaticMutex;
|
||||
|
||||
static ARGC: AtomicIsize = AtomicIsize::new(0);
|
||||
static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
|
||||
// We never call `ENV_LOCK.init()`, so it is UB to attempt to
|
||||
// acquire this mutex reentrantly!
|
||||
static LOCK: Mutex = Mutex::new();
|
||||
static LOCK: StaticMutex = StaticMutex::new();
|
||||
|
||||
unsafe fn really_init(argc: isize, argv: *const *const u8) {
|
||||
let _guard = LOCK.lock();
|
||||
|
|
|
@ -21,7 +21,7 @@ use crate::slice;
|
|||
use crate::str;
|
||||
use crate::sys::cvt;
|
||||
use crate::sys::fd;
|
||||
use crate::sys_common::mutex::{Mutex, MutexGuard};
|
||||
use crate::sys_common::mutex::{StaticMutex, StaticMutexGuard};
|
||||
use crate::vec;
|
||||
|
||||
use libc::{c_char, c_int, c_void};
|
||||
|
@ -470,10 +470,9 @@ pub unsafe fn environ() -> *mut *const *const c_char {
|
|||
&mut environ
|
||||
}
|
||||
|
||||
pub unsafe fn env_lock() -> MutexGuard<'static> {
|
||||
// We never call `ENV_LOCK.init()`, so it is UB to attempt to
|
||||
// acquire this mutex reentrantly!
|
||||
static ENV_LOCK: Mutex = Mutex::new();
|
||||
pub unsafe fn env_lock() -> StaticMutexGuard<'static> {
|
||||
// It is UB to attempt to acquire this mutex reentrantly!
|
||||
static ENV_LOCK: StaticMutex = StaticMutex::new();
|
||||
ENV_LOCK.lock()
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue