1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 use crate::NoPoisonMutex; 16 use std::ops::{Deref, DerefMut}; 17 18 /// A mutual exclusion primitive useful for protecting shared data 19 pub struct Mutex<T>(std::sync::Mutex<T>); 20 21 impl<T> NoPoisonMutex<T> for Mutex<T> { 22 type MutexGuard<'a> = std::sync::MutexGuard<'a, T> where T: 'a; 23 lock(&self) -> Self::MutexGuard<'_>24 fn lock(&self) -> Self::MutexGuard<'_> { 25 self.0.lock().unwrap_or_else(|poison| poison.into_inner()) 26 } 27 try_lock(&self) -> Option<Self::MutexGuard<'_>>28 fn try_lock(&self) -> Option<Self::MutexGuard<'_>> { 29 match self.0.try_lock() { 30 Ok(guard) => Some(guard), 31 Err(std::sync::TryLockError::Poisoned(guard)) => Some(guard.into_inner()), 32 Err(std::sync::TryLockError::WouldBlock) => None, 33 } 34 } 35 new(value: T) -> Self36 fn new(value: T) -> Self { 37 Self(std::sync::Mutex::new(value)) 38 } 39 } 40 41 /// A reader-writer lock 42 /// This type of lock allows a number of readers or at most one writer at any point in time. 43 /// The write portion of this lock typically allows modification of the underlying data (exclusive access) 44 /// and the read portion of this lock typically allows for read-only access (shared access). 45 pub struct RwLock<T>(std::sync::RwLock<T>); 46 47 impl<T> RwLock<T> { 48 /// Creates a new instance of an `RwLock<T>` which is unlocked. new(value: T) -> Self49 pub const fn new(value: T) -> Self { 50 Self(std::sync::RwLock::new(value)) 51 } 52 } 53 54 impl<T> crate::RwLock<T> for RwLock<T> { 55 type RwLockReadGuard<'a> = RwLockReadGuard<'a, T> where T: 'a; 56 57 type RwLockWriteGuard<'a> = RwLockWriteGuard<'a, T> where T: 'a; 58 read(&self) -> Self::RwLockReadGuard<'_>59 fn read(&self) -> Self::RwLockReadGuard<'_> { 60 RwLockReadGuard(self.0.read().unwrap_or_else(|e| e.into_inner())) 61 } 62 write(&self) -> Self::RwLockWriteGuard<'_>63 fn write(&self) -> Self::RwLockWriteGuard<'_> { 64 RwLockWriteGuard(self.0.write().unwrap_or_else(|e| e.into_inner())) 65 } 66 } 67 68 /// RAII structure used to release the shared read access of a lock when dropped. 69 pub struct RwLockReadGuard<'a, T>(std::sync::RwLockReadGuard<'a, T>); 70 71 impl<'a, T> RwLockReadGuard<'a, T> { 72 /// Make a new MappedRwLockReadGuard for a component of the locked data. map<U, M>(s: Self, mapping: M) -> MappedRwLockReadGuard<'a, T, U, M> where M: RwMapping<Arg = T, Ret = U>,73 pub fn map<U, M>(s: Self, mapping: M) -> MappedRwLockReadGuard<'a, T, U, M> 74 where 75 M: RwMapping<Arg = T, Ret = U>, 76 { 77 MappedRwLockReadGuard { mapping, guard: s } 78 } 79 } 80 81 impl<'a, T> Deref for RwLockReadGuard<'a, T> { 82 type Target = T; 83 deref(&self) -> &Self::Target84 fn deref(&self) -> &Self::Target { 85 self.0.deref() 86 } 87 } 88 89 /// An RAII read lock guard returned by RwLockReadGuard::map, which can point to a subfield of the protected data. 90 pub struct MappedRwLockReadGuard<'a, T, U, M> 91 where 92 M: RwMapping<Arg = T, Ret = U>, 93 { 94 mapping: M, 95 guard: RwLockReadGuard<'a, T>, 96 } 97 98 impl<'a, T, U, M> Deref for MappedRwLockReadGuard<'a, T, U, M> 99 where 100 M: RwMapping<Arg = T, Ret = U>, 101 { 102 type Target = U; 103 deref(&self) -> &Self::Target104 fn deref(&self) -> &Self::Target { 105 self.mapping.map(&*self.guard) 106 } 107 } 108 109 /// RAII structure used to release the exclusive write access of a lock when dropped. 110 pub struct RwLockWriteGuard<'a, T>(std::sync::RwLockWriteGuard<'a, T>); 111 112 impl<'a, T> RwLockWriteGuard<'a, T> { 113 /// Make a new MappedRwLockWriteGuard for a component of the locked data. map<U, M>(s: Self, mapping: M) -> MappedRwLockWriteGuard<'a, T, U, M> where M: RwMapping<Arg = T, Ret = U>,114 pub fn map<U, M>(s: Self, mapping: M) -> MappedRwLockWriteGuard<'a, T, U, M> 115 where 116 M: RwMapping<Arg = T, Ret = U>, 117 { 118 MappedRwLockWriteGuard { mapping, guard: s } 119 } 120 } 121 122 impl<'a, T> Deref for RwLockWriteGuard<'a, T> { 123 type Target = T; 124 deref(&self) -> &Self::Target125 fn deref(&self) -> &Self::Target { 126 self.0.deref() 127 } 128 } 129 130 impl<'a, T> DerefMut for RwLockWriteGuard<'a, T> { deref_mut(&mut self) -> &mut Self::Target131 fn deref_mut(&mut self) -> &mut Self::Target { 132 self.0.deref_mut() 133 } 134 } 135 136 /// An RAII read lock guard returned by RwLockWriteGuard::map, which can point to a subfield of the protected data. 137 pub struct MappedRwLockWriteGuard<'a, T, U, M> 138 where 139 M: RwMapping<Arg = T, Ret = U>, 140 { 141 mapping: M, 142 guard: RwLockWriteGuard<'a, T>, 143 } 144 145 impl<'a, P, T, M> Deref for MappedRwLockWriteGuard<'a, P, T, M> 146 where 147 M: RwMapping<Arg = P, Ret = T>, 148 { 149 type Target = T; 150 deref(&self) -> &Self::Target151 fn deref(&self) -> &Self::Target { 152 self.mapping.map(&*self.guard) 153 } 154 } 155 156 impl<'a, P, T, M> DerefMut for MappedRwLockWriteGuard<'a, P, T, M> 157 where 158 M: RwMapping<Arg = P, Ret = T>, 159 { deref_mut(&mut self) -> &mut Self::Target160 fn deref_mut(&mut self) -> &mut Self::Target { 161 self.mapping.map_mut(&mut *self.guard) 162 } 163 } 164 165 /// Mapping functions which define how to map from one locked data type to a component of that locked data 166 pub trait RwMapping { 167 /// The original locked data type 168 type Arg; 169 /// The returned mapped locked data type which is a component of the original locked data 170 type Ret; 171 /// Maps from Arg into Ret map<'a>(&self, arg: &'a Self::Arg) -> &'a Self::Ret172 fn map<'a>(&self, arg: &'a Self::Arg) -> &'a Self::Ret; 173 /// Mutably maps from Arg into Ret map_mut<'a>(&self, arg: &'a mut Self::Arg) -> &'a mut Self::Ret174 fn map_mut<'a>(&self, arg: &'a mut Self::Arg) -> &'a mut Self::Ret; 175 } 176