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::Handle; 16 use core::ops::{Deref, DerefMut}; 17 use lock_adapter::stdlib::RwMapping; 18 use std::collections::HashMap; 19 use std::marker::PhantomData; 20 21 /// A RAII read lock guard for an object in a [`HandleMap`](crate::HandleMap) 22 /// pointed-to by a given [`Handle`]. When this struct is 23 /// dropped, the underlying read lock on the associated 24 /// shard will be dropped. 25 pub struct ObjectReadGuardImpl<'a, T: 'a> { 26 pub(crate) guard: lock_adapter::stdlib::MappedRwLockReadGuard< 27 'a, 28 <Self as ObjectReadGuard>::Arg, 29 <Self as ObjectReadGuard>::Ret, 30 <Self as ObjectReadGuard>::Mapping, 31 >, 32 } 33 34 /// Trait implemented for an ObjectReadGuard which defines the associated types of the guard and a 35 /// mapping for how the guard is retrieved from its parent object 36 pub trait ObjectReadGuard: Deref<Target = Self::Ret> { 37 /// The mapping which defines how a guard is retrieved for `Self::Ret` from `Self::Arg` 38 type Mapping: RwMapping<Arg = Self::Arg, Ret = Self::Ret>; 39 /// The argument type input to the mapping functions 40 type Arg; 41 /// The Return type of the mapping functions 42 type Ret; 43 } 44 45 impl<'a, T> Deref for ObjectReadGuardImpl<'a, T> { 46 type Target = T; 47 deref(&self) -> &Self::Target48 fn deref(&self) -> &Self::Target { 49 self.guard.deref() 50 } 51 } 52 53 pub struct ObjectReadGuardMapping<'a, T> { 54 pub(crate) handle: Handle, 55 pub(crate) _marker: PhantomData<&'a T>, 56 } 57 58 impl<'a, T> RwMapping for ObjectReadGuardMapping<'a, T> { 59 type Arg = HashMap<Handle, T>; 60 type Ret = T; 61 map<'b>(&self, arg: &'b Self::Arg) -> &'b Self::Ret62 fn map<'b>(&self, arg: &'b Self::Arg) -> &'b Self::Ret { 63 #[allow(clippy::expect_used)] 64 arg.get(&self.handle).expect("We know that the entry exists, since we've locked the shard and already checked that it exists prior to handing out this new, mapped read-lock.") 65 } 66 map_mut<'b>(&self, arg: &'b mut Self::Arg) -> &'b mut Self::Ret67 fn map_mut<'b>(&self, arg: &'b mut Self::Arg) -> &'b mut Self::Ret { 68 #[allow(clippy::expect_used)] 69 arg.get_mut(&self.handle).expect("We know that the entry exists, since we've locked the shard and already checked that it exists prior to handing out this new, mapped read-lock.") 70 } 71 } 72 73 impl<'a, T> ObjectReadGuard for ObjectReadGuardImpl<'a, T> { 74 type Mapping = ObjectReadGuardMapping<'a, T>; 75 type Arg = HashMap<Handle, T>; 76 type Ret = T; 77 } 78 79 /// A RAII read-write lock guard for an object in a [`HandleMap`](crate::HandleMap) 80 /// pointed-to by a given [`Handle`]. When this struct is 81 /// dropped, the underlying read-write lock on the associated 82 /// shard will be dropped. 83 pub struct ObjectReadWriteGuardImpl<'a, T: 'a> { 84 pub(crate) guard: lock_adapter::stdlib::MappedRwLockWriteGuard< 85 'a, 86 <Self as ObjectReadWriteGuard>::Arg, 87 <Self as ObjectReadWriteGuard>::Ret, 88 <Self as ObjectReadWriteGuard>::Mapping, 89 >, 90 } 91 92 /// Trait implemented for an object read guard which defines the associated types of the guard and a 93 /// mapping for how the guard is retrieved from its parent object 94 pub trait ObjectReadWriteGuard: Deref<Target = Self::Ret> + DerefMut<Target = Self::Ret> { 95 /// The mapping which defines how a guard is retrieved for `Ret` from `Arg` 96 type Mapping: RwMapping<Arg = Self::Arg, Ret = Self::Ret>; 97 /// The argument type input to the mapping functions 98 type Arg; 99 /// The Return type of the mapping functions 100 type Ret; 101 } 102 103 pub struct ObjectReadWriteGuardMapping<'a, T> { 104 pub(crate) handle: Handle, 105 pub(crate) _marker: PhantomData<&'a T>, 106 } 107 108 impl<'a, T> Deref for ObjectReadWriteGuardImpl<'a, T> { 109 type Target = T; 110 deref(&self) -> &Self::Target111 fn deref(&self) -> &Self::Target { 112 self.guard.deref() 113 } 114 } 115 116 impl<'a, T> DerefMut for ObjectReadWriteGuardImpl<'a, T> { deref_mut(&mut self) -> &mut Self::Target117 fn deref_mut(&mut self) -> &mut Self::Target { 118 self.guard.deref_mut() 119 } 120 } 121 122 impl<'a, T> ObjectReadWriteGuard for ObjectReadWriteGuardImpl<'a, T> { 123 type Mapping = ObjectReadWriteGuardMapping<'a, T>; 124 type Arg = HashMap<Handle, T>; 125 type Ret = T; 126 } 127 128 impl<'a, T> RwMapping for ObjectReadWriteGuardMapping<'a, T> { 129 type Arg = HashMap<Handle, T>; 130 type Ret = T; 131 map<'b>(&self, arg: &'b Self::Arg) -> &'b Self::Ret132 fn map<'b>(&self, arg: &'b Self::Arg) -> &'b Self::Ret { 133 #[allow(clippy::expect_used)] 134 arg.get(&self.handle) 135 .expect("Caller must verify that provided hande exists") 136 } 137 map_mut<'b>(&self, arg: &'b mut Self::Arg) -> &'b mut Self::Ret138 fn map_mut<'b>(&self, arg: &'b mut Self::Arg) -> &'b mut Self::Ret { 139 #[allow(clippy::expect_used)] 140 arg.get_mut(&self.handle) 141 .expect("Caller must verify that provided hande exists") 142 } 143 } 144