use std::cell::UnsafeCell;
use std::fmt;
use std::marker::PhantomData;
use std::mem::ManuallyDrop;
use std::ops::Deref;
use std::ops::DerefMut;
use std::ptr::NonNull;
use std::sync::Arc;
use crate::internal;
#[cfg(test)]
mod test;
pub struct Mutex<T: ?Sized> {
s: internal::Semaphore,
c: UnsafeCell<T>,
}
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
impl<T> From<T> for Mutex<T> {
fn from(t: T) -> Self {
Self::new(t)
}
}
impl<T: Default> Default for Mutex<T> {
fn default() -> Self {
Self::new(T::default())
}
}
impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut d = f.debug_struct("Mutex");
match self.try_lock() {
Some(inner) => d.field("data", &&*inner),
None => d.field("data", &format_args!("<locked>")),
};
d.finish()
}
}
impl<T> Mutex<T> {
pub const fn new(t: T) -> Self {
let s = internal::Semaphore::new(1);
let c = UnsafeCell::new(t);
Self { s, c }
}
pub fn into_inner(self) -> T {
self.c.into_inner()
}
}
impl<T: ?Sized> Mutex<T> {
pub async fn lock(&self) -> MutexGuard<'_, T> {
self.s.acquire(1).await;
MutexGuard { lock: self }
}
pub fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
if self.s.try_acquire(1) {
let guard = MutexGuard { lock: self };
Some(guard)
} else {
None
}
}
pub async fn lock_owned(self: Arc<Self>) -> OwnedMutexGuard<T> {
self.s.acquire(1).await;
OwnedMutexGuard { lock: self }
}
pub fn try_lock_owned(self: Arc<Self>) -> Option<OwnedMutexGuard<T>> {
if self.s.try_acquire(1) {
let guard = OwnedMutexGuard { lock: self };
Some(guard)
} else {
None
}
}
pub fn get_mut(&mut self) -> &mut T {
self.c.get_mut()
}
}
#[must_use = "if unused the Mutex will immediately unlock"]
pub struct MutexGuard<'a, T: ?Sized> {
lock: &'a Mutex<T>,
}
pub(crate) fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a Mutex<T> {
guard.lock
}
unsafe impl<T: ?Sized + Send + Sync> Sync for MutexGuard<'_, T> {}
impl<T: ?Sized> Drop for MutexGuard<'_, T> {
fn drop(&mut self) {
self.lock.s.release(1);
}
}
impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
}
impl<T: ?Sized> Deref for MutexGuard<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &*self.lock.c.get() }
}
}
impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.lock.c.get() }
}
}
impl<'a, T: ?Sized> MutexGuard<'a, T> {
pub fn map<U, F>(mut orig: Self, f: F) -> MappedMutexGuard<'a, U>
where
F: FnOnce(&mut T) -> &mut U,
U: ?Sized,
{
let d = NonNull::from(f(&mut *orig));
let orig = ManuallyDrop::new(orig);
MappedMutexGuard {
d,
s: &orig.lock.s,
variance: PhantomData,
}
}
pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
where
F: FnOnce(&mut T) -> Option<&mut U>,
U: ?Sized,
{
match f(&mut *orig) {
Some(d) => {
let d = NonNull::from(d);
let orig = ManuallyDrop::new(orig);
Ok(MappedMutexGuard {
d,
s: &orig.lock.s,
variance: PhantomData,
})
}
None => Err(orig),
}
}
}
#[must_use = "if unused the Mutex will immediately unlock"]
pub struct OwnedMutexGuard<T: ?Sized> {
lock: Arc<Mutex<T>>,
}
pub(crate) fn owned_guard_lock<T: ?Sized>(guard: &OwnedMutexGuard<T>) -> Arc<Mutex<T>> {
guard.lock.clone()
}
unsafe impl<T: ?Sized + Send + Sync> Sync for OwnedMutexGuard<T> {}
impl<T: ?Sized> Drop for OwnedMutexGuard<T> {
fn drop(&mut self) {
self.lock.s.release(1);
}
}
impl<T: ?Sized + fmt::Debug> fmt::Debug for OwnedMutexGuard<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
impl<T: ?Sized + fmt::Display> fmt::Display for OwnedMutexGuard<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
}
impl<T: ?Sized> Deref for OwnedMutexGuard<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &*self.lock.c.get() }
}
}
impl<T: ?Sized> DerefMut for OwnedMutexGuard<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.lock.c.get() }
}
}
impl<T: ?Sized> OwnedMutexGuard<T> {
pub fn map<U, F>(mut orig: Self, f: F) -> OwnedMappedMutexGuard<T, U>
where
F: FnOnce(&mut T) -> &mut U,
U: ?Sized,
{
let d = NonNull::from(f(&mut *orig));
let guard = ManuallyDrop::new(orig);
let lock = unsafe { std::ptr::read(&guard.lock) };
OwnedMappedMutexGuard {
lock,
d,
variance: PhantomData,
}
}
pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<OwnedMappedMutexGuard<T, U>, Self>
where
F: FnOnce(&mut T) -> Option<&mut U>,
U: ?Sized,
{
match f(&mut *orig) {
Some(d) => {
let d = NonNull::from(d);
let guard = ManuallyDrop::new(orig);
let lock = unsafe { std::ptr::read(&guard.lock) };
Ok(OwnedMappedMutexGuard {
lock,
d,
variance: PhantomData,
})
}
None => Err(orig),
}
}
}
#[must_use = "if unused the Mutex will immediately unlock"]
pub struct MappedMutexGuard<'a, T: ?Sized> {
d: NonNull<T>,
s: &'a internal::Semaphore,
variance: PhantomData<&'a mut T>,
}
unsafe impl<T: ?Sized + Send> Send for MappedMutexGuard<'_, T> {}
unsafe impl<T: ?Sized + Sync> Sync for MappedMutexGuard<'_, T> {}
impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
fn drop(&mut self) {
self.s.release(1);
}
}
impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
impl<T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
}
impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { self.d.as_ref() }
}
}
impl<T: ?Sized> DerefMut for MappedMutexGuard<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.d.as_mut() }
}
}
impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
pub fn map<U, F>(mut orig: Self, f: F) -> MappedMutexGuard<'a, U>
where
F: FnOnce(&mut T) -> &mut U,
U: ?Sized,
{
let d = NonNull::from(f(&mut *orig));
let orig = ManuallyDrop::new(orig);
MappedMutexGuard {
d,
s: orig.s,
variance: PhantomData,
}
}
pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
where
F: FnOnce(&mut T) -> Option<&mut U>,
U: ?Sized,
{
match f(&mut *orig) {
Some(d) => {
let d = NonNull::from(d);
let orig = ManuallyDrop::new(orig);
Ok(MappedMutexGuard {
d,
s: orig.s,
variance: PhantomData,
})
}
None => Err(orig),
}
}
}
#[must_use = "if unused the Mutex will immediately unlock"]
pub struct OwnedMappedMutexGuard<T: ?Sized, U: ?Sized> {
lock: Arc<Mutex<T>>,
d: NonNull<U>,
variance: PhantomData<U>,
}
unsafe impl<T: ?Sized + Send, U: ?Sized + Send> Send for OwnedMappedMutexGuard<T, U> {}
unsafe impl<T: ?Sized + Send + Sync, U: ?Sized + Send + Sync> Sync for OwnedMappedMutexGuard<T, U> {}
impl<T: ?Sized, U: ?Sized> Drop for OwnedMappedMutexGuard<T, U> {
fn drop(&mut self) {
self.lock.s.release(1);
}
}
impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for OwnedMappedMutexGuard<T, U> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
impl<T: ?Sized, U: ?Sized + fmt::Display> fmt::Display for OwnedMappedMutexGuard<T, U> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
}
impl<T: ?Sized, U: ?Sized> Deref for OwnedMappedMutexGuard<T, U> {
type Target = U;
fn deref(&self) -> &Self::Target {
unsafe { self.d.as_ref() }
}
}
impl<T: ?Sized, U: ?Sized> DerefMut for OwnedMappedMutexGuard<T, U> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.d.as_mut() }
}
}
impl<T: ?Sized, U: ?Sized> OwnedMappedMutexGuard<T, U> {
pub fn map<V, F>(mut orig: Self, f: F) -> OwnedMappedMutexGuard<T, V>
where
F: FnOnce(&mut U) -> &mut V,
V: ?Sized,
{
let d = NonNull::from(f(&mut *orig));
let orig = ManuallyDrop::new(orig);
let lock = unsafe { std::ptr::read(&orig.lock) };
OwnedMappedMutexGuard {
lock,
d,
variance: PhantomData,
}
}
pub fn filter_map<V, F>(mut orig: Self, f: F) -> Result<OwnedMappedMutexGuard<T, V>, Self>
where
F: FnOnce(&mut U) -> Option<&mut V>,
V: ?Sized,
{
match f(&mut *orig) {
Some(d) => {
let d = NonNull::from(d);
let orig = ManuallyDrop::new(orig);
let lock = unsafe { std::ptr::read(&orig.lock) };
Ok(OwnedMappedMutexGuard {
lock,
d,
variance: PhantomData,
})
}
None => Err(orig),
}
}
}