mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Auto merge of #95173 - m-ou-se:sys-locks-module, r=dtolnay
Move std::sys::{mutex, condvar, rwlock} to std::sys::locks. This cleans up the the std::sys modules a bit by putting the locks in a single module called `locks` rather than spread over the three modules `mutex`, `condvar`, and `rwlock`. This makes it easier to organise lock implementations, which helps with https://github.com/rust-lang/rust/issues/93740.
This commit is contained in:
commit
36748cf814
@ -2,7 +2,7 @@ use crate::ffi::c_void;
|
||||
use crate::ptr;
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
use crate::sys::hermit::abi;
|
||||
use crate::sys::mutex::Mutex;
|
||||
use crate::sys::locks::Mutex;
|
||||
use crate::time::Duration;
|
||||
|
||||
// The implementation is inspired by Andrew D. Birrell's paper
|
||||
|
@ -22,14 +22,12 @@ pub mod alloc;
|
||||
pub mod args;
|
||||
#[path = "../unix/cmath.rs"]
|
||||
pub mod cmath;
|
||||
pub mod condvar;
|
||||
pub mod env;
|
||||
pub mod fd;
|
||||
pub mod fs;
|
||||
#[path = "../unsupported/io.rs"]
|
||||
pub mod io;
|
||||
pub mod memchr;
|
||||
pub mod mutex;
|
||||
pub mod net;
|
||||
pub mod os;
|
||||
#[path = "../unix/os_str.rs"]
|
||||
@ -40,7 +38,6 @@ pub mod path;
|
||||
pub mod pipe;
|
||||
#[path = "../unsupported/process.rs"]
|
||||
pub mod process;
|
||||
pub mod rwlock;
|
||||
pub mod stdio;
|
||||
pub mod thread;
|
||||
pub mod thread_local_dtor;
|
||||
@ -48,6 +45,16 @@ pub mod thread_local_dtor;
|
||||
pub mod thread_local_key;
|
||||
pub mod time;
|
||||
|
||||
mod condvar;
|
||||
mod mutex;
|
||||
mod rwlock;
|
||||
|
||||
pub mod locks {
|
||||
pub use super::condvar::*;
|
||||
pub use super::mutex::*;
|
||||
pub use super::rwlock::*;
|
||||
}
|
||||
|
||||
use crate::io::ErrorKind;
|
||||
|
||||
#[allow(unused_extern_crates)]
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::sys::condvar::Condvar;
|
||||
use crate::sys::mutex::Mutex;
|
||||
use crate::sys::locks::{Condvar, Mutex};
|
||||
|
||||
pub struct RWLock {
|
||||
lock: Mutex,
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! POSIX conditional variable implementation based on user-space wait queues.
|
||||
use super::{abi, error::expect_success_aborting, spin::SpinMutex, task, time::with_tmos_strong};
|
||||
use crate::{mem::replace, ptr::NonNull, sys::mutex::Mutex, time::Duration};
|
||||
use crate::{mem::replace, ptr::NonNull, sys::locks::Mutex, time::Duration};
|
||||
|
||||
// The implementation is inspired by the queue-based implementation shown in
|
||||
// Andrew D. Birrell's paper "Implementing Condition Variables with Semaphores"
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::sys::mutex::Mutex;
|
||||
use crate::sys::locks::Mutex;
|
||||
use crate::time::Duration;
|
||||
|
||||
use super::waitqueue::{SpinMutex, WaitQueue, WaitVariable};
|
||||
|
@ -15,7 +15,6 @@ pub mod alloc;
|
||||
pub mod args;
|
||||
#[path = "../unix/cmath.rs"]
|
||||
pub mod cmath;
|
||||
pub mod condvar;
|
||||
pub mod env;
|
||||
pub mod fd;
|
||||
#[path = "../unsupported/fs.rs"]
|
||||
@ -23,7 +22,6 @@ pub mod fs;
|
||||
#[path = "../unsupported/io.rs"]
|
||||
pub mod io;
|
||||
pub mod memchr;
|
||||
pub mod mutex;
|
||||
pub mod net;
|
||||
pub mod os;
|
||||
#[path = "../unix/os_str.rs"]
|
||||
@ -33,12 +31,21 @@ pub mod path;
|
||||
pub mod pipe;
|
||||
#[path = "../unsupported/process.rs"]
|
||||
pub mod process;
|
||||
pub mod rwlock;
|
||||
pub mod stdio;
|
||||
pub mod thread;
|
||||
pub mod thread_local_key;
|
||||
pub mod time;
|
||||
|
||||
mod condvar;
|
||||
mod mutex;
|
||||
mod rwlock;
|
||||
|
||||
pub mod locks {
|
||||
pub use super::condvar::*;
|
||||
pub use super::mutex::*;
|
||||
pub use super::rwlock::*;
|
||||
}
|
||||
|
||||
// SAFETY: must be called only once during runtime initialization.
|
||||
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
|
||||
pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
||||
|
@ -37,14 +37,21 @@ pub mod path;
|
||||
pub mod pipe;
|
||||
#[path = "../unsupported/process.rs"]
|
||||
pub mod process;
|
||||
pub mod rwlock;
|
||||
pub mod stdio;
|
||||
pub use self::itron::{condvar, mutex, thread};
|
||||
pub use self::itron::thread;
|
||||
pub mod memchr;
|
||||
pub mod thread_local_dtor;
|
||||
pub mod thread_local_key;
|
||||
pub mod time;
|
||||
|
||||
mod rwlock;
|
||||
|
||||
pub mod locks {
|
||||
pub use super::itron::condvar::*;
|
||||
pub use super::itron::mutex::*;
|
||||
pub use super::rwlock::*;
|
||||
}
|
||||
|
||||
// SAFETY: must be called only once during runtime initialization.
|
||||
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
|
||||
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
|
||||
|
8
library/std/src/sys/unix/locks/mod.rs
Normal file
8
library/std/src/sys/unix/locks/mod.rs
Normal file
@ -0,0 +1,8 @@
|
||||
mod pthread_condvar;
|
||||
mod pthread_mutex;
|
||||
mod pthread_remutex;
|
||||
mod pthread_rwlock;
|
||||
pub use pthread_condvar::{Condvar, MovableCondvar};
|
||||
pub use pthread_mutex::{MovableMutex, Mutex};
|
||||
pub use pthread_remutex::ReentrantMutex;
|
||||
pub use pthread_rwlock::{MovableRWLock, RWLock};
|
@ -1,5 +1,5 @@
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::sys::mutex::{self, Mutex};
|
||||
use crate::sys::locks::{pthread_mutex, Mutex};
|
||||
use crate::time::Duration;
|
||||
|
||||
pub struct Condvar {
|
||||
@ -79,7 +79,7 @@ impl Condvar {
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn wait(&self, mutex: &Mutex) {
|
||||
let r = libc::pthread_cond_wait(self.inner.get(), mutex::raw(mutex));
|
||||
let r = libc::pthread_cond_wait(self.inner.get(), pthread_mutex::raw(mutex));
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ impl Condvar {
|
||||
let timeout =
|
||||
sec.map(|s| libc::timespec { tv_sec: s, tv_nsec: nsec as _ }).unwrap_or(TIMESPEC_MAX);
|
||||
|
||||
let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex), &timeout);
|
||||
let r = libc::pthread_cond_timedwait(self.inner.get(), pthread_mutex::raw(mutex), &timeout);
|
||||
assert!(r == libc::ETIMEDOUT || r == 0);
|
||||
r == 0
|
||||
}
|
||||
@ -169,7 +169,7 @@ impl Condvar {
|
||||
.unwrap_or(TIMESPEC_MAX);
|
||||
|
||||
// And wait!
|
||||
let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex), &timeout);
|
||||
let r = libc::pthread_cond_timedwait(self.inner.get(), pthread_mutex::raw(mutex), &timeout);
|
||||
debug_assert!(r == libc::ETIMEDOUT || r == 0);
|
||||
|
||||
// ETIMEDOUT is not a totally reliable method of determining timeout due
|
@ -90,49 +90,7 @@ impl Mutex {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReentrantMutex {
|
||||
inner: UnsafeCell<libc::pthread_mutex_t>,
|
||||
}
|
||||
|
||||
unsafe impl Send for ReentrantMutex {}
|
||||
unsafe impl Sync for ReentrantMutex {}
|
||||
|
||||
impl ReentrantMutex {
|
||||
pub const unsafe fn uninitialized() -> ReentrantMutex {
|
||||
ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
|
||||
}
|
||||
|
||||
pub unsafe fn init(&self) {
|
||||
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
|
||||
cvt_nz(libc::pthread_mutexattr_init(attr.as_mut_ptr())).unwrap();
|
||||
let attr = PthreadMutexAttr(&mut attr);
|
||||
cvt_nz(libc::pthread_mutexattr_settype(attr.0.as_mut_ptr(), libc::PTHREAD_MUTEX_RECURSIVE))
|
||||
.unwrap();
|
||||
cvt_nz(libc::pthread_mutex_init(self.inner.get(), attr.0.as_ptr())).unwrap();
|
||||
}
|
||||
|
||||
pub unsafe fn lock(&self) {
|
||||
let result = libc::pthread_mutex_lock(self.inner.get());
|
||||
debug_assert_eq!(result, 0);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn try_lock(&self) -> bool {
|
||||
libc::pthread_mutex_trylock(self.inner.get()) == 0
|
||||
}
|
||||
|
||||
pub unsafe fn unlock(&self) {
|
||||
let result = libc::pthread_mutex_unlock(self.inner.get());
|
||||
debug_assert_eq!(result, 0);
|
||||
}
|
||||
|
||||
pub unsafe fn destroy(&self) {
|
||||
let result = libc::pthread_mutex_destroy(self.inner.get());
|
||||
debug_assert_eq!(result, 0);
|
||||
}
|
||||
}
|
||||
|
||||
struct PthreadMutexAttr<'a>(&'a mut MaybeUninit<libc::pthread_mutexattr_t>);
|
||||
pub(super) struct PthreadMutexAttr<'a>(pub &'a mut MaybeUninit<libc::pthread_mutexattr_t>);
|
||||
|
||||
impl Drop for PthreadMutexAttr<'_> {
|
||||
fn drop(&mut self) {
|
46
library/std/src/sys/unix/locks/pthread_remutex.rs
Normal file
46
library/std/src/sys/unix/locks/pthread_remutex.rs
Normal file
@ -0,0 +1,46 @@
|
||||
use super::pthread_mutex::PthreadMutexAttr;
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::sys::cvt_nz;
|
||||
|
||||
pub struct ReentrantMutex {
|
||||
inner: UnsafeCell<libc::pthread_mutex_t>,
|
||||
}
|
||||
|
||||
unsafe impl Send for ReentrantMutex {}
|
||||
unsafe impl Sync for ReentrantMutex {}
|
||||
|
||||
impl ReentrantMutex {
|
||||
pub const unsafe fn uninitialized() -> ReentrantMutex {
|
||||
ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
|
||||
}
|
||||
|
||||
pub unsafe fn init(&self) {
|
||||
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
|
||||
cvt_nz(libc::pthread_mutexattr_init(attr.as_mut_ptr())).unwrap();
|
||||
let attr = PthreadMutexAttr(&mut attr);
|
||||
cvt_nz(libc::pthread_mutexattr_settype(attr.0.as_mut_ptr(), libc::PTHREAD_MUTEX_RECURSIVE))
|
||||
.unwrap();
|
||||
cvt_nz(libc::pthread_mutex_init(self.inner.get(), attr.0.as_ptr())).unwrap();
|
||||
}
|
||||
|
||||
pub unsafe fn lock(&self) {
|
||||
let result = libc::pthread_mutex_lock(self.inner.get());
|
||||
debug_assert_eq!(result, 0);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn try_lock(&self) -> bool {
|
||||
libc::pthread_mutex_trylock(self.inner.get()) == 0
|
||||
}
|
||||
|
||||
pub unsafe fn unlock(&self) {
|
||||
let result = libc::pthread_mutex_unlock(self.inner.get());
|
||||
debug_assert_eq!(result, 0);
|
||||
}
|
||||
|
||||
pub unsafe fn destroy(&self) {
|
||||
let result = libc::pthread_mutex_destroy(self.inner.get());
|
||||
debug_assert_eq!(result, 0);
|
||||
}
|
||||
}
|
@ -14,7 +14,6 @@ pub mod android;
|
||||
pub mod args;
|
||||
#[path = "../unix/cmath.rs"]
|
||||
pub mod cmath;
|
||||
pub mod condvar;
|
||||
pub mod env;
|
||||
pub mod fd;
|
||||
pub mod fs;
|
||||
@ -24,8 +23,8 @@ pub mod io;
|
||||
pub mod kernel_copy;
|
||||
#[cfg(target_os = "l4re")]
|
||||
mod l4re;
|
||||
pub mod locks;
|
||||
pub mod memchr;
|
||||
pub mod mutex;
|
||||
#[cfg(not(target_os = "l4re"))]
|
||||
pub mod net;
|
||||
#[cfg(target_os = "l4re")]
|
||||
@ -36,7 +35,6 @@ pub mod path;
|
||||
pub mod pipe;
|
||||
pub mod process;
|
||||
pub mod rand;
|
||||
pub mod rwlock;
|
||||
pub mod stack_overflow;
|
||||
pub mod stdio;
|
||||
pub mod thread;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::sys::mutex::Mutex;
|
||||
use crate::sys::locks::Mutex;
|
||||
use crate::time::Duration;
|
||||
|
||||
pub struct Condvar {}
|
6
library/std/src/sys/unsupported/locks/mod.rs
Normal file
6
library/std/src/sys/unsupported/locks/mod.rs
Normal file
@ -0,0 +1,6 @@
|
||||
mod condvar;
|
||||
mod mutex;
|
||||
mod rwlock;
|
||||
pub use condvar::{Condvar, MovableCondvar};
|
||||
pub use mutex::{MovableMutex, Mutex, ReentrantMutex};
|
||||
pub use rwlock::{MovableRWLock, RWLock};
|
@ -4,11 +4,10 @@ pub mod alloc;
|
||||
pub mod args;
|
||||
#[path = "../unix/cmath.rs"]
|
||||
pub mod cmath;
|
||||
pub mod condvar;
|
||||
pub mod env;
|
||||
pub mod fs;
|
||||
pub mod io;
|
||||
pub mod mutex;
|
||||
pub mod locks;
|
||||
pub mod net;
|
||||
pub mod os;
|
||||
#[path = "../unix/os_str.rs"]
|
||||
@ -17,7 +16,6 @@ pub mod os_str;
|
||||
pub mod path;
|
||||
pub mod pipe;
|
||||
pub mod process;
|
||||
pub mod rwlock;
|
||||
pub mod stdio;
|
||||
pub mod thread;
|
||||
#[cfg(target_thread_local)]
|
||||
|
@ -22,14 +22,12 @@ pub mod alloc;
|
||||
pub mod args;
|
||||
#[path = "../unix/cmath.rs"]
|
||||
pub mod cmath;
|
||||
#[path = "../unsupported/condvar.rs"]
|
||||
pub mod condvar;
|
||||
pub mod env;
|
||||
pub mod fd;
|
||||
pub mod fs;
|
||||
pub mod io;
|
||||
#[path = "../unsupported/mutex.rs"]
|
||||
pub mod mutex;
|
||||
#[path = "../unsupported/locks/mod.rs"]
|
||||
pub mod locks;
|
||||
pub mod net;
|
||||
pub mod os;
|
||||
#[path = "../unix/os_str.rs"]
|
||||
@ -40,8 +38,6 @@ pub mod path;
|
||||
pub mod pipe;
|
||||
#[path = "../unsupported/process.rs"]
|
||||
pub mod process;
|
||||
#[path = "../unsupported/rwlock.rs"]
|
||||
pub mod rwlock;
|
||||
pub mod stdio;
|
||||
pub mod thread;
|
||||
#[path = "../unsupported/thread_local_dtor.rs"]
|
||||
|
@ -2,7 +2,7 @@ use crate::arch::wasm32;
|
||||
use crate::cmp;
|
||||
use crate::mem;
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
use crate::sys::mutex::Mutex;
|
||||
use crate::sys::locks::Mutex;
|
||||
use crate::time::Duration;
|
||||
|
||||
pub struct Condvar {
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::sys::condvar::Condvar;
|
||||
use crate::sys::mutex::Mutex;
|
||||
use crate::sys::locks::{Condvar, Mutex};
|
||||
|
||||
pub struct RWLock {
|
||||
lock: Mutex,
|
||||
|
@ -50,22 +50,23 @@ pub mod time;
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_feature = "atomics")] {
|
||||
#[path = "atomics/condvar.rs"]
|
||||
pub mod condvar;
|
||||
mod condvar;
|
||||
#[path = "atomics/mutex.rs"]
|
||||
pub mod mutex;
|
||||
mod mutex;
|
||||
#[path = "atomics/rwlock.rs"]
|
||||
pub mod rwlock;
|
||||
mod rwlock;
|
||||
pub mod locks {
|
||||
pub use super::condvar::*;
|
||||
pub use super::mutex::*;
|
||||
pub use super::rwlock::*;
|
||||
}
|
||||
#[path = "atomics/futex.rs"]
|
||||
pub mod futex;
|
||||
#[path = "atomics/thread.rs"]
|
||||
pub mod thread;
|
||||
} else {
|
||||
#[path = "../unsupported/condvar.rs"]
|
||||
pub mod condvar;
|
||||
#[path = "../unsupported/mutex.rs"]
|
||||
pub mod mutex;
|
||||
#[path = "../unsupported/rwlock.rs"]
|
||||
pub mod rwlock;
|
||||
#[path = "../unsupported/locks/mod.rs"]
|
||||
pub mod locks;
|
||||
#[path = "../unsupported/thread.rs"]
|
||||
pub mod thread;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::sys::c;
|
||||
use crate::sys::mutex::{self, Mutex};
|
||||
use crate::sys::locks::{mutex, Mutex};
|
||||
use crate::sys::os;
|
||||
use crate::time::Duration;
|
||||
|
||||
@ -31,7 +31,7 @@ impl Condvar {
|
||||
let r = c::SleepConditionVariableSRW(
|
||||
self.inner.get(),
|
||||
mutex::raw(mutex),
|
||||
super::dur2timeout(dur),
|
||||
crate::sys::windows::dur2timeout(dur),
|
||||
0,
|
||||
);
|
||||
if r == 0 {
|
6
library/std/src/sys/windows/locks/mod.rs
Normal file
6
library/std/src/sys/windows/locks/mod.rs
Normal file
@ -0,0 +1,6 @@
|
||||
mod condvar;
|
||||
mod mutex;
|
||||
mod rwlock;
|
||||
pub use condvar::{Condvar, MovableCondvar};
|
||||
pub use mutex::{MovableMutex, Mutex, ReentrantMutex};
|
||||
pub use rwlock::{MovableRWLock, RWLock};
|
@ -16,13 +16,12 @@ pub mod alloc;
|
||||
pub mod args;
|
||||
pub mod c;
|
||||
pub mod cmath;
|
||||
pub mod condvar;
|
||||
pub mod env;
|
||||
pub mod fs;
|
||||
pub mod handle;
|
||||
pub mod io;
|
||||
pub mod locks;
|
||||
pub mod memchr;
|
||||
pub mod mutex;
|
||||
pub mod net;
|
||||
pub mod os;
|
||||
pub mod os_str;
|
||||
@ -30,7 +29,6 @@ pub mod path;
|
||||
pub mod pipe;
|
||||
pub mod process;
|
||||
pub mod rand;
|
||||
pub mod rwlock;
|
||||
pub mod thread;
|
||||
pub mod thread_local_dtor;
|
||||
pub mod thread_local_key;
|
||||
|
@ -1,11 +1,10 @@
|
||||
use crate::sys::condvar as imp;
|
||||
use crate::sys::mutex as mutex_imp;
|
||||
use crate::sys::locks as imp;
|
||||
use crate::sys_common::mutex::MovableMutex;
|
||||
use crate::time::Duration;
|
||||
|
||||
mod check;
|
||||
|
||||
type CondvarCheck = <mutex_imp::MovableMutex as check::CondvarCheck>::Check;
|
||||
type CondvarCheck = <imp::MovableMutex as check::CondvarCheck>::Check;
|
||||
|
||||
/// An OS-based condition variable.
|
||||
pub struct Condvar {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||
use crate::sys::mutex as mutex_imp;
|
||||
use crate::sys::locks as imp;
|
||||
use crate::sys_common::mutex::MovableMutex;
|
||||
|
||||
pub trait CondvarCheck {
|
||||
@ -8,7 +8,7 @@ pub trait CondvarCheck {
|
||||
|
||||
/// For boxed mutexes, a `Condvar` will check it's only ever used with the same
|
||||
/// mutex, based on its (stable) address.
|
||||
impl CondvarCheck for Box<mutex_imp::Mutex> {
|
||||
impl CondvarCheck for Box<imp::Mutex> {
|
||||
type Check = SameMutexCheck;
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ impl SameMutexCheck {
|
||||
Self { addr: AtomicUsize::new(0) }
|
||||
}
|
||||
pub fn verify(&self, mutex: &MovableMutex) {
|
||||
let addr = mutex.raw() as *const mutex_imp::Mutex as usize;
|
||||
let addr = mutex.raw() as *const imp::Mutex as usize;
|
||||
match self.addr.compare_exchange(0, addr, Ordering::SeqCst, Ordering::SeqCst) {
|
||||
Ok(_) => {} // Stored the address
|
||||
Err(n) if n == addr => {} // Lost a race to store the same address
|
||||
@ -33,7 +33,7 @@ impl SameMutexCheck {
|
||||
|
||||
/// Unboxed mutexes may move, so `Condvar` can not require its address to stay
|
||||
/// constant.
|
||||
impl CondvarCheck for mutex_imp::Mutex {
|
||||
impl CondvarCheck for imp::Mutex {
|
||||
type Check = NoCheck;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::sys::mutex as imp;
|
||||
use crate::sys::locks as imp;
|
||||
|
||||
/// An OS-based mutual exclusion lock, meant for use in static variables.
|
||||
///
|
||||
|
@ -5,7 +5,7 @@ use crate::marker::PhantomPinned;
|
||||
use crate::ops::Deref;
|
||||
use crate::panic::{RefUnwindSafe, UnwindSafe};
|
||||
use crate::pin::Pin;
|
||||
use crate::sys::mutex as sys;
|
||||
use crate::sys::locks as sys;
|
||||
|
||||
/// A re-entrant mutual exclusion
|
||||
///
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::sys::rwlock as imp;
|
||||
use crate::sys::locks as imp;
|
||||
|
||||
/// An OS-based reader-writer lock, meant for use in static variables.
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user