1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
//! A mutual exclusion primitive useful for protecting shared data. //! //! See [`Mutex`] for more details. //! //! [`Mutex`]: struct.Mutex.html use core::cell::UnsafeCell; use core::ops::{Deref, DerefMut}; use core::sync::atomic::AtomicBool; use core::sync::atomic::Ordering::*; /// A mutual exclusion primitive useful for protecting shared data. /// /// This mutex supports only [`try_lock`] method, and hence never blocks. /// /// [`try_lock`]: #method.try_lock pub struct Mutex<T> { lock: AtomicBool, data: UnsafeCell<T>, } /// An RAII implementation of a "scoped lock" of a mutex. When this structure is /// dropped (falls out of scope), the lock will be unlocked. /// /// The data protected by the mutex can be accessed through this guard via its /// `Deref` and `DerefMut` implementations. /// /// This structure is created by the [`try_lock`] method on [`Mutex`]. /// /// [`Mutex`]: struct.Mutex.html /// [`try_lock`]: struct.Mutex.html#method.try_lock #[must_use] pub struct MutexGuard<'a, T: 'a> { lock: &'a Mutex<T>, } unsafe impl<T: Send> Send for Mutex<T> {} unsafe impl<T: Send> Sync for Mutex<T> {} impl<'a, T> !Send for MutexGuard<'a, T> {} unsafe impl<'a, T: Sync> Sync for MutexGuard<'a, T> {} impl<T> Mutex<T> { /// Creates a new mutex in an unlocked state ready for use. /// /// # Examples /// /// ``` /// use drone_core::sync::Mutex; /// /// let mutex = Mutex::new(0); /// ``` #[inline(always)] pub const fn new(t: T) -> Self { Self { lock: AtomicBool::new(false), data: UnsafeCell::new(t), } } /// Attempts to acquire this lock. /// /// If the lock could not be acquired at this time, then `None` is returned. /// Otherwise, a RAII guard is returned. The lock will be unlocked when the /// guard is dropped. /// /// # Examples /// /// ``` /// use drone_core::sync::Mutex; /// /// let mutex = Mutex::new(1); /// /// match mutex.try_lock() { /// Some(n) => assert_eq!(*n, 1), /// None => unreachable!(), /// }; /// ``` #[inline(always)] pub fn try_lock(&self) -> Option<MutexGuard<T>> { if !self.lock.swap(true, Acquire) { Some(MutexGuard { lock: self }) } else { None } } /// Consumes this mutex, returning the underlying data. /// /// # Examples /// /// ``` /// use drone_core::sync::Mutex; /// /// let mutex = Mutex::new(0); /// assert_eq!(mutex.into_inner(), 0); /// ``` #[inline(always)] pub fn into_inner(self) -> T { let Self { data, .. } = self; unsafe { data.into_inner() } } /// Returns a mutable reference to the underlying data. /// /// Since this call borrows the `Mutex` mutably, no actual locking needs to /// take place --- the mutable borrow statically guarantees no locks exist. /// /// # Examples /// /// ``` /// use drone_core::sync::Mutex; /// /// let mut mutex = Mutex::new(0); /// *mutex.get_mut() = 10; /// assert_eq!(*mutex.try_lock().unwrap(), 10); /// ``` #[inline(always)] pub fn get_mut(&mut self) -> &mut T { unsafe { &mut *self.data.get() } } } impl<T: Default> Default for Mutex<T> { /// Creates a `Mutex<T>`, with the `Default` value for T. #[inline(always)] fn default() -> Self { Mutex::new(Default::default()) } } impl<'a, T> Deref for MutexGuard<'a, T> { type Target = T; #[inline(always)] fn deref(&self) -> &T { unsafe { &*self.lock.data.get() } } } impl<'a, T> DerefMut for MutexGuard<'a, T> { #[inline(always)] fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.lock.data.get() } } } impl<'a, T> Drop for MutexGuard<'a, T> { #[inline(always)] fn drop(&mut self) { self.lock.lock.store(false, Release); } }