summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBotahamec <botahamec@outlook.com>2024-05-21 13:18:10 -0400
committerBotahamec <botahamec@outlook.com>2024-05-21 13:18:10 -0400
commit6e3aa5182604b30ef75ba5676e9f677cc1d18fe3 (patch)
treed8e23a82c8151c4b49c15f49707d96651764db39 /src
parent875d5c4ad6e0c2a78c15476584fc686121b340d3 (diff)
parentc344021797b7e1f8027bd9d1302908f0767e362b (diff)
Merge remote-tracking branch 'origin/0.2' into 0.2
Diffstat (limited to 'src')
-rw-r--r--src/collection.rs11
-rw-r--r--src/collection/boxed_collection.rs10
-rw-r--r--src/collection/guard.rs6
-rw-r--r--src/collection/owned_collection.rs11
-rw-r--r--src/collection/ref_collection.rs12
-rw-r--r--src/collection/retry_collection.rs138
-rw-r--r--src/lockable.rs274
-rw-r--r--src/rwlock.rs6
-rw-r--r--src/rwlock/read_lock.rs16
-rw-r--r--src/rwlock/write_lock.rs16
10 files changed, 315 insertions, 185 deletions
diff --git a/src/collection.rs b/src/collection.rs
index 93adf16..a11d60c 100644
--- a/src/collection.rs
+++ b/src/collection.rs
@@ -1,4 +1,4 @@
-use std::{marker::PhantomData, ptr::NonNull};
+use std::marker::PhantomData;
use crate::{
key::Keyable,
@@ -9,6 +9,7 @@ mod boxed_collection;
mod guard;
mod owned_collection;
mod ref_collection;
+mod retry_collection;
pub struct OwnedLockCollection<L> {
data: L,
@@ -25,9 +26,13 @@ pub struct RefLockCollection<'a, L> {
pub struct BoxedLockCollection<'a, L>(RefLockCollection<'a, L>);
+pub struct RetryingLockCollection<L> {
+ data: L,
+}
+
/// A RAII guard for a generic [`Lockable`] type.
-pub struct LockGuard<'a, 'key: 'a, L: Lockable<'a>, Key: Keyable + 'key> {
- guard: L::Guard,
+pub struct LockGuard<'g, 'key: 'g, L: Lockable + 'g, Key: Keyable + 'key> {
+ guard: L::Guard<'g>,
key: Key,
_phantom: PhantomData<&'key ()>,
}
diff --git a/src/collection/boxed_collection.rs b/src/collection/boxed_collection.rs
index bcb941b..1aae1e4 100644
--- a/src/collection/boxed_collection.rs
+++ b/src/collection/boxed_collection.rs
@@ -26,7 +26,7 @@ impl<'a, L> Drop for BoxedLockCollection<'a, L> {
}
}
-impl<'a, L: OwnedLockable<'a> + 'a> BoxedLockCollection<'a, L> {
+impl<'a, L: OwnedLockable> BoxedLockCollection<'a, L> {
#[must_use]
pub fn new(data: L) -> Self {
let boxed = Box::leak(Box::new(data));
@@ -34,18 +34,18 @@ impl<'a, L: OwnedLockable<'a> + 'a> BoxedLockCollection<'a, L> {
}
}
-impl<'a, L: OwnedLockable<'a> + 'a> BoxedLockCollection<'a, &'a L> {
+impl<'a, L: OwnedLockable> BoxedLockCollection<'a, &'a L> {
#[must_use]
pub fn new_ref(data: &'a L) -> Self {
let boxed = Box::leak(Box::new(data));
- // this is a reference to an OwnedLockable, which can't possibly
- // contain inner duplicates
+ // safety: this is a reference to an OwnedLockable, which can't
+ // possibly contain inner duplicates
Self(unsafe { RefLockCollection::new_unchecked(boxed) })
}
}
-impl<'a, L: Lockable<'a> + 'a> BoxedLockCollection<'a, L> {
+impl<'a, L: Lockable> BoxedLockCollection<'a, L> {
#[must_use]
pub unsafe fn new_unchecked(data: L) -> Self {
let boxed = Box::leak(Box::new(data));
diff --git a/src/collection/guard.rs b/src/collection/guard.rs
index 3b98d29..e3ffb21 100644
--- a/src/collection/guard.rs
+++ b/src/collection/guard.rs
@@ -4,15 +4,15 @@ use crate::{key::Keyable, Lockable};
use super::LockGuard;
-impl<'a, 'key: 'a, L: Lockable<'a>, Key: Keyable> Deref for LockGuard<'a, 'key, L, Key> {
- type Target = L::Guard;
+impl<'a, 'key: 'a, L: Lockable + 'a, Key: Keyable> Deref for LockGuard<'a, 'key, L, Key> {
+ type Target = L::Guard<'a>;
fn deref(&self) -> &Self::Target {
&self.guard
}
}
-impl<'a, 'key: 'a, L: Lockable<'a>, Key: Keyable> DerefMut for LockGuard<'a, 'key, L, Key> {
+impl<'a, 'key: 'a, L: Lockable + 'a, Key: Keyable> DerefMut for LockGuard<'a, 'key, L, Key> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.guard
}
diff --git a/src/collection/owned_collection.rs b/src/collection/owned_collection.rs
index dbc9a45..ea8f2f2 100644
--- a/src/collection/owned_collection.rs
+++ b/src/collection/owned_collection.rs
@@ -4,22 +4,19 @@ use crate::{lockable::Lock, Keyable, Lockable, OwnedLockable};
use super::{LockGuard, OwnedLockCollection};
-fn get_locks<'a, L: Lockable<'a> + 'a>(data: &'a L) -> Vec<&'a dyn Lock> {
+fn get_locks<L: Lockable>(data: &L) -> Vec<&dyn Lock> {
let mut locks = Vec::new();
data.get_ptrs(&mut locks);
locks
}
-impl<'a, L: OwnedLockable<'a>> OwnedLockCollection<L> {
+impl<L: OwnedLockable> OwnedLockCollection<L> {
#[must_use]
pub const fn new(data: L) -> Self {
Self { data }
}
- pub fn lock<'s: 'a, 'key, Key: Keyable + 'key>(
- &'s self,
- key: Key,
- ) -> LockGuard<'a, 'key, L, Key> {
+ pub fn lock<'a, 'key, Key: Keyable + 'key>(&'a self, key: Key) -> LockGuard<'a, 'key, L, Key> {
let locks = get_locks(&self.data);
for lock in locks {
// safety: we have the thread key, and these locks happen in a
@@ -36,7 +33,7 @@ impl<'a, L: OwnedLockable<'a>> OwnedLockCollection<L> {
}
}
- pub fn try_lock<'key: 'a, Key: Keyable + 'key>(
+ pub fn try_lock<'a, 'key: 'a, Key: Keyable + 'key>(
&'a self,
key: Key,
) -> Option<LockGuard<'a, 'key, L, Key>> {
diff --git a/src/collection/ref_collection.rs b/src/collection/ref_collection.rs
index 9dfa0e9..41f6b16 100644
--- a/src/collection/ref_collection.rs
+++ b/src/collection/ref_collection.rs
@@ -5,7 +5,7 @@ use crate::{key::Keyable, lockable::Lock, Lockable, OwnedLockable};
use super::{LockGuard, RefLockCollection};
#[must_use]
-fn get_locks<'a, L: Lockable<'a> + 'a>(data: &'a L) -> Vec<&'a dyn Lock> {
+fn get_locks<L: Lockable>(data: &L) -> Vec<&dyn Lock> {
let mut locks = Vec::new();
data.get_ptrs(&mut locks);
locks.sort_by_key(|lock| std::ptr::from_ref(*lock));
@@ -19,19 +19,19 @@ fn contains_duplicates(l: &[&dyn Lock]) -> bool {
.any(|window| std::ptr::eq(window[0], window[1]))
}
-impl<'a, L: Lockable<'a>> AsRef<L> for RefLockCollection<'a, L> {
+impl<'a, L: Lockable> AsRef<L> for RefLockCollection<'a, L> {
fn as_ref(&self) -> &L {
self.data
}
}
-impl<'a, L: Lockable<'a>> AsRef<Self> for RefLockCollection<'a, L> {
+impl<'a, L: Lockable> AsRef<Self> for RefLockCollection<'a, L> {
fn as_ref(&self) -> &Self {
self
}
}
-impl<'a, L: Lockable<'a>> AsMut<Self> for RefLockCollection<'a, L> {
+impl<'a, L: Lockable> AsMut<Self> for RefLockCollection<'a, L> {
fn as_mut(&mut self) -> &mut Self {
self
}
@@ -49,7 +49,7 @@ where
}
}
-impl<'a, L: OwnedLockable<'a> + 'a> RefLockCollection<'a, L> {
+impl<'a, L: OwnedLockable> RefLockCollection<'a, L> {
/// Creates a new collection of owned locks.
///
/// Because the locks are owned, there's no need to do any checks for
@@ -72,7 +72,7 @@ impl<'a, L: OwnedLockable<'a> + 'a> RefLockCollection<'a, L> {
}
}
-impl<'a, L: Lockable<'a>> RefLockCollection<'a, L> {
+impl<'a, L: Lockable> RefLockCollection<'a, L> {
/// Creates a new collections of locks.
///
/// # Safety
diff --git a/src/collection/retry_collection.rs b/src/collection/retry_collection.rs
new file mode 100644
index 0000000..73f9e18
--- /dev/null
+++ b/src/collection/retry_collection.rs
@@ -0,0 +1,138 @@
+use std::marker::PhantomData;
+
+use crate::{lockable::Lock, Keyable, Lockable, OwnedLockable};
+
+use super::{LockGuard, RetryingLockCollection};
+
+fn contains_duplicates<L: Lockable>(data: L) -> bool {
+ let mut locks = Vec::new();
+ data.get_ptrs(&mut locks);
+ let mut locks: Vec<_> = locks.into_iter().map(|l| l as *const dyn Lock).collect();
+ locks.sort_unstable();
+ locks.windows(2).any(|w| std::ptr::addr_eq(w[0], w[1]))
+}
+
+impl<L: OwnedLockable> RetryingLockCollection<L> {
+ #[must_use]
+ pub const fn new(data: L) -> Self {
+ Self { data }
+ }
+}
+
+impl<'a, L: OwnedLockable> RetryingLockCollection<&'a L> {
+ #[must_use]
+ pub const fn new_ref(data: &'a L) -> Self {
+ Self { data }
+ }
+}
+
+impl<L: Lockable> RetryingLockCollection<L> {
+ #[must_use]
+ pub const unsafe fn new_unchecked(data: L) -> Self {
+ Self { data }
+ }
+
+ pub fn try_new(data: L) -> Option<Self> {
+ contains_duplicates(&data).then_some(Self { data })
+ }
+
+ pub fn lock<'a, 'key: 'a, Key: Keyable + 'key>(
+ &'a self,
+ key: Key,
+ ) -> LockGuard<'a, 'key, L, Key> {
+ let mut first_index = 0;
+ let mut locks = Vec::new();
+ self.data.get_ptrs(&mut locks);
+
+ if locks.is_empty() {
+ return LockGuard {
+ // safety: there's no data being returned
+ guard: unsafe { self.data.guard() },
+ key,
+ _phantom: PhantomData,
+ };
+ }
+
+ let guard = unsafe {
+ 'outer: loop {
+ // safety: we have the thread key
+ locks[first_index].lock();
+ for (i, lock) in locks.iter().enumerate() {
+ if i == first_index {
+ continue;
+ }
+
+ // safety: we have the thread key
+ if !lock.try_lock() {
+ for lock in locks.iter().take(i) {
+ // safety: we already locked all of these
+ lock.unlock();
+ }
+
+ if first_index >= i {
+ // safety: this is already locked and can't be unlocked
+ // by the previous loop
+ locks[first_index].unlock();
+ }
+
+ first_index = i;
+ continue 'outer;
+ }
+ }
+
+ // safety: we locked all the data
+ break self.data.guard();
+ }
+ };
+
+ LockGuard {
+ guard,
+ key,
+ _phantom: PhantomData,
+ }
+ }
+
+ pub fn try_lock<'a, 'key: 'a, Key: Keyable + 'key>(
+ &'a self,
+ key: Key,
+ ) -> Option<LockGuard<'a, 'key, L, Key>> {
+ let mut locks = Vec::new();
+ self.data.get_ptrs(&mut locks);
+
+ if locks.is_empty() {
+ return Some(LockGuard {
+ // safety: there's no data being returned
+ guard: unsafe { self.data.guard() },
+ key,
+ _phantom: PhantomData,
+ });
+ }
+
+ let guard = unsafe {
+ for (i, lock) in locks.iter().enumerate() {
+ // safety: we have the thread key
+ if !lock.try_lock() {
+ for lock in locks.iter().take(i) {
+ // safety: we already locked all of these
+ lock.unlock();
+ }
+ return None;
+ }
+ }
+
+ // safety: we locked all the data
+ self.data.guard()
+ };
+
+ Some(LockGuard {
+ guard,
+ key,
+ _phantom: PhantomData,
+ })
+ }
+
+ pub fn unlock<'key, Key: Keyable + 'key>(guard: LockGuard<'_, 'key, L, Key>) -> Key {
+ drop(guard.guard);
+ guard.key
+ }
+}
diff --git a/src/lockable.rs b/src/lockable.rs
index a09b84b..a5646e1 100644
--- a/src/lockable.rs
+++ b/src/lockable.rs
@@ -47,14 +47,16 @@ pub unsafe trait Lock: Send + Sync {
unsafe fn unlock(&self);
}
-pub unsafe trait Lockable<'a> {
+pub unsafe trait Lockable {
/// The guard returned that does not hold a key
- type Guard;
+ type Guard<'g>
+ where
+ Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>);
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>);
#[must_use]
- unsafe fn guard(&'a self) -> Self::Guard;
+ unsafe fn guard(&self) -> Self::Guard<'_>;
}
/// A type that may be locked and unlocked, and is known to be the only valid
@@ -64,7 +66,7 @@ pub unsafe trait Lockable<'a> {
///
/// There must not be any two values which can unlock the value at the same
/// time, i.e., this must either be an owned value or a mutable reference.
-pub unsafe trait OwnedLockable<'a>: Lockable<'a> {}
+pub unsafe trait OwnedLockable: Lockable {}
unsafe impl<T: Send, R: RawMutex + Send + Sync> Lock for Mutex<T, R> {
unsafe fn lock(&self) {
@@ -94,138 +96,134 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lock for RwLock<T, R> {
}
}
-unsafe impl<'a, T: Send + 'a, R: RawMutex + Send + Sync + 'a> Lockable<'a> for Mutex<T, R> {
- type Guard = MutexRef<'a, T, R>;
+unsafe impl<T: Send, R: RawMutex + Send + Sync> Lockable for Mutex<T, R> {
+ type Guard<'g> = MutexRef<'g, T, R> where Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
ptrs.push(self);
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
MutexRef::new(self)
}
}
-unsafe impl<'a, T: Send + 'a, R: RawRwLock + Send + Sync + 'a> Lockable<'a> for RwLock<T, R> {
- type Guard = RwLockWriteRef<'a, T, R>;
+unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for RwLock<T, R> {
+ type Guard<'g> = RwLockWriteRef<'g, T, R> where Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
ptrs.push(self);
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
RwLockWriteRef::new(self)
}
}
-unsafe impl<'a, T: Send + 'a, R: RawMutex + Send + Sync + 'a> OwnedLockable<'a> for Mutex<T, R> {}
+unsafe impl<T: Send, R: RawMutex + Send + Sync> OwnedLockable for Mutex<T, R> {}
-unsafe impl<'a, T: Send + 'a, R: RawRwLock + Send + Sync + 'a> OwnedLockable<'a> for RwLock<T, R> {}
+unsafe impl<T: Send, R: RawRwLock + Send + Sync> OwnedLockable for RwLock<T, R> {}
-unsafe impl<'a, T: Send + 'a, R: RawRwLock + Send + Sync + 'a> Lockable<'a> for ReadLock<'a, T, R> {
- type Guard = RwLockReadRef<'a, T, R>;
+unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for ReadLock<T, R> {
+ type Guard<'g> = RwLockReadRef<'g, T, R> where Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
ptrs.push(self.as_ref());
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
RwLockReadRef::new(self.as_ref())
}
}
-unsafe impl<'a, T: Send + 'a, R: RawRwLock + Send + Sync + 'a> Lockable<'a>
- for WriteLock<'a, T, R>
-{
- type Guard = RwLockWriteRef<'a, T, R>;
+unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for WriteLock<T, R> {
+ type Guard<'g> = RwLockWriteRef<'g, T, R> where Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
ptrs.push(self.as_ref());
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
RwLockWriteRef::new(self.as_ref())
}
}
-unsafe impl<'a, T: Lockable<'a>> Lockable<'a> for &'a T {
- type Guard = T::Guard;
+unsafe impl<T: Lockable> Lockable for &T {
+ type Guard<'g> = T::Guard<'g> where Self: 'g;
- fn get_ptrs(&self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
(*self).get_ptrs(ptrs);
}
- unsafe fn guard(&self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
(*self).guard()
}
}
-unsafe impl<'a, T: Lockable<'a>> Lockable<'a> for &mut T {
- type Guard = T::Guard;
+unsafe impl<T: Lockable> Lockable for &mut T {
+ type Guard<'g> = T::Guard<'g> where Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
(**self).get_ptrs(ptrs)
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
(**self).guard()
}
}
-unsafe impl<'a, T: OwnedLockable<'a>> OwnedLockable<'a> for &mut T {}
+unsafe impl<T: OwnedLockable> OwnedLockable for &mut T {}
-unsafe impl<'a, A: Lockable<'a>> Lockable<'a> for (A,) {
- type Guard = (A::Guard,);
+unsafe impl<A: Lockable> Lockable for (A,) {
+ type Guard<'g> = (A::Guard<'g>,) where Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
self.0.get_ptrs(ptrs);
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
(self.0.guard(),)
}
}
-unsafe impl<'a, A: Lockable<'a>, B: Lockable<'a>> Lockable<'a> for (A, B) {
- type Guard = (A::Guard, B::Guard);
+unsafe impl<A: Lockable, B: Lockable> Lockable for (A, B) {
+ type Guard<'g> = (A::Guard<'g>, B::Guard<'g>) where Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
self.0.get_ptrs(ptrs);
self.1.get_ptrs(ptrs);
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
(self.0.guard(), self.1.guard())
}
}
-unsafe impl<'a, A: Lockable<'a>, B: Lockable<'a>, C: Lockable<'a>> Lockable<'a> for (A, B, C) {
- type Guard = (A::Guard, B::Guard, C::Guard);
+unsafe impl<A: Lockable, B: Lockable, C: Lockable> Lockable for (A, B, C) {
+ type Guard<'g> = (A::Guard<'g>, B::Guard<'g>, C::Guard<'g>) where Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
self.0.get_ptrs(ptrs);
self.1.get_ptrs(ptrs);
self.2.get_ptrs(ptrs);
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
(self.0.guard(), self.1.guard(), self.2.guard())
}
}
-unsafe impl<'a, A: Lockable<'a>, B: Lockable<'a>, C: Lockable<'a>, D: Lockable<'a>> Lockable<'a>
- for (A, B, C, D)
-{
- type Guard = (A::Guard, B::Guard, C::Guard, D::Guard);
+unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable> Lockable for (A, B, C, D) {
+ type Guard<'g> = (A::Guard<'g>, B::Guard<'g>, C::Guard<'g>, D::Guard<'g>) where Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
self.0.get_ptrs(ptrs);
self.1.get_ptrs(ptrs);
self.2.get_ptrs(ptrs);
self.3.get_ptrs(ptrs);
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
(
self.0.guard(),
self.1.guard(),
@@ -235,12 +233,18 @@ unsafe impl<'a, A: Lockable<'a>, B: Lockable<'a>, C: Lockable<'a>, D: Lockable<'
}
}
-unsafe impl<'a, A: Lockable<'a>, B: Lockable<'a>, C: Lockable<'a>, D: Lockable<'a>, E: Lockable<'a>>
- Lockable<'a> for (A, B, C, D, E)
+unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable, E: Lockable> Lockable
+ for (A, B, C, D, E)
{
- type Guard = (A::Guard, B::Guard, C::Guard, D::Guard, E::Guard);
-
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ type Guard<'g> = (
+ A::Guard<'g>,
+ B::Guard<'g>,
+ C::Guard<'g>,
+ D::Guard<'g>,
+ E::Guard<'g>,
+ ) where Self: 'g;
+
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
self.0.get_ptrs(ptrs);
self.1.get_ptrs(ptrs);
self.2.get_ptrs(ptrs);
@@ -248,7 +252,7 @@ unsafe impl<'a, A: Lockable<'a>, B: Lockable<'a>, C: Lockable<'a>, D: Lockable<'
self.4.get_ptrs(ptrs);
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
(
self.0.guard(),
self.1.guard(),
@@ -259,19 +263,19 @@ unsafe impl<'a, A: Lockable<'a>, B: Lockable<'a>, C: Lockable<'a>, D: Lockable<'
}
}
-unsafe impl<
- 'a,
- A: Lockable<'a>,
- B: Lockable<'a>,
- C: Lockable<'a>,
- D: Lockable<'a>,
- E: Lockable<'a>,
- F: Lockable<'a>,
- > Lockable<'a> for (A, B, C, D, E, F)
+unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable, E: Lockable, F: Lockable> Lockable
+ for (A, B, C, D, E, F)
{
- type Guard = (A::Guard, B::Guard, C::Guard, D::Guard, E::Guard, F::Guard);
-
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ type Guard<'g> = (
+ A::Guard<'g>,
+ B::Guard<'g>,
+ C::Guard<'g>,
+ D::Guard<'g>,
+ E::Guard<'g>,
+ F::Guard<'g>,
+ ) where Self: 'g;
+
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
self.0.get_ptrs(ptrs);
self.1.get_ptrs(ptrs);
self.2.get_ptrs(ptrs);
@@ -280,7 +284,7 @@ unsafe impl<
self.5.get_ptrs(ptrs);
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
(
self.0.guard(),
self.1.guard(),
@@ -292,28 +296,20 @@ unsafe impl<
}
}
-unsafe impl<
- 'a,
- A: Lockable<'a>,
- B: Lockable<'a>,
- C: Lockable<'a>,
- D: Lockable<'a>,
- E: Lockable<'a>,
- F: Lockable<'a>,
- G: Lockable<'a>,
- > Lockable<'a> for (A, B, C, D, E, F, G)
+unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable, E: Lockable, F: Lockable, G: Lockable>
+ Lockable for (A, B, C, D, E, F, G)
{
- type Guard = (
- A::Guard,
- B::Guard,
- C::Guard,
- D::Guard,
- E::Guard,
- F::Guard,
- G::Guard,
- );
-
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ type Guard<'g> = (
+ A::Guard<'g>,
+ B::Guard<'g>,
+ C::Guard<'g>,
+ D::Guard<'g>,
+ E::Guard<'g>,
+ F::Guard<'g>,
+ G::Guard<'g>,
+ ) where Self: 'g;
+
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
self.0.get_ptrs(ptrs);
self.1.get_ptrs(ptrs);
self.2.get_ptrs(ptrs);
@@ -323,7 +319,7 @@ unsafe impl<
self.6.get_ptrs(ptrs);
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
(
self.0.guard(),
self.1.guard(),
@@ -336,71 +332,63 @@ unsafe impl<
}
}
-unsafe impl<'a, A: OwnedLockable<'a>> OwnedLockable<'a> for (A,) {}
-unsafe impl<'a, A: OwnedLockable<'a>, B: OwnedLockable<'a>> OwnedLockable<'a> for (A, B) {}
+unsafe impl<A: OwnedLockable> OwnedLockable for (A,) {}
+unsafe impl<A: OwnedLockable, B: OwnedLockable> OwnedLockable for (A, B) {}
-unsafe impl<'a, A: OwnedLockable<'a>, B: OwnedLockable<'a>, C: OwnedLockable<'a>> OwnedLockable<'a>
- for (A, B, C)
-{
-}
+unsafe impl<A: OwnedLockable, B: OwnedLockable, C: OwnedLockable> OwnedLockable for (A, B, C) {}
-unsafe impl<
- 'a,
- A: OwnedLockable<'a>,
- B: OwnedLockable<'a>,
- C: OwnedLockable<'a>,
- D: OwnedLockable<'a>,
- > OwnedLockable<'a> for (A, B, C, D)
+unsafe impl<A: OwnedLockable, B: OwnedLockable, C: OwnedLockable, D: OwnedLockable> OwnedLockable
+ for (A, B, C, D)
{
}
unsafe impl<
'a,
- A: OwnedLockable<'a>,
- B: OwnedLockable<'a>,
- C: OwnedLockable<'a>,
- D: OwnedLockable<'a>,
- E: OwnedLockable<'a>,
- > OwnedLockable<'a> for (A, B, C, D, E)
+ A: OwnedLockable,
+ B: OwnedLockable,
+ C: OwnedLockable,
+ D: OwnedLockable,
+ E: OwnedLockable,
+ > OwnedLockable for (A, B, C, D, E)
{
}
unsafe impl<
'a,
- A: OwnedLockable<'a>,
- B: OwnedLockable<'a>,
- C: OwnedLockable<'a>,
- D: OwnedLockable<'a>,
- E: OwnedLockable<'a>,
- F: OwnedLockable<'a>,
- > OwnedLockable<'a> for (A, B, C, D, E, F)
+ A: OwnedLockable,
+ B: OwnedLockable,
+ C: OwnedLockable,
+ D: OwnedLockable,
+ E: OwnedLockable,
+ F: OwnedLockable,
+ > OwnedLockable for (A, B, C, D, E, F)
{
}
unsafe impl<
'a,
- A: OwnedLockable<'a>,
- B: OwnedLockable<'a>,
- C: OwnedLockable<'a>,
- D: OwnedLockable<'a>,
- E: OwnedLockable<'a>,
- F: OwnedLockable<'a>,
- G: OwnedLockable<'a>,
- > OwnedLockable<'a> for (A, B, C, D, E, F, G)
+ A: OwnedLockable,
+ B: OwnedLockable,
+ C: OwnedLockable,
+ D: OwnedLockable,
+ E: OwnedLockable,
+ F: OwnedLockable,
+ G: OwnedLockable,
+ > OwnedLockable for (A, B, C, D, E, F, G)
{
}
-unsafe impl<'a, T: Lockable<'a>, const N: usize> Lockable<'a> for [T; N] {
- type Guard = [T::Guard; N];
+unsafe impl<T: Lockable, const N: usize> Lockable for [T; N] {
+ type Guard<'g> = [T::Guard<'g>; N] where Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
for lock in self {
lock.get_ptrs(ptrs);
}
}
- unsafe fn guard(&'a self) -> Self::Guard {
- let mut guards = MaybeUninit::<[MaybeUninit<T::Guard>; N]>::uninit().assume_init();
+ unsafe fn guard<'g>(&'g self) -> Self::Guard<'g> {
+ let mut guards = MaybeUninit::<[MaybeUninit<T::Guard<'g>>; N]>::uninit().assume_init();
for i in 0..N {
guards[i].write(self[i].guard());
}
@@ -409,16 +397,16 @@ unsafe impl<'a, T: Lockable<'a>, const N: usize> Lockable<'a> for [T; N] {
}
}
-unsafe impl<'a, T: Lockable<'a>> Lockable<'a> for Box<[T]> {
- type Guard = Box<[T::Guard]>;
+unsafe impl<T: Lockable> Lockable for Box<[T]> {
+ type Guard<'g> = Box<[T::Guard<'g>]> where Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
for lock in self.iter() {
lock.get_ptrs(ptrs);
}
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
let mut guards = Vec::new();
for lock in self.iter() {
guards.push(lock.guard());
@@ -428,16 +416,16 @@ unsafe impl<'a, T: Lockable<'a>> Lockable<'a> for Box<[T]> {
}
}
-unsafe impl<'a, T: Lockable<'a>> Lockable<'a> for Vec<T> {
- type Guard = Vec<T::Guard>;
+unsafe impl<T: Lockable> Lockable for Vec<T> {
+ type Guard<'g> = Vec<T::Guard<'g>> where Self: 'g;
- fn get_ptrs(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
+ fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) {
for lock in self {
lock.get_ptrs(ptrs);
}
}
- unsafe fn guard(&'a self) -> Self::Guard {
+ unsafe fn guard(&self) -> Self::Guard<'_> {
let mut guards = Vec::new();
for lock in self {
guards.push(lock.guard());
@@ -447,6 +435,6 @@ unsafe impl<'a, T: Lockable<'a>> Lockable<'a> for Vec<T> {
}
}
-unsafe impl<'a, T: OwnedLockable<'a>, const N: usize> OwnedLockable<'a> for [T; N] {}
-unsafe impl<'a, T: OwnedLockable<'a>> OwnedLockable<'a> for Box<[T]> {}
-unsafe impl<'a, T: OwnedLockable<'a>> OwnedLockable<'a> for Vec<T> {}
+unsafe impl<T: OwnedLockable, const N: usize> OwnedLockable for [T; N] {}
+unsafe impl<T: OwnedLockable> OwnedLockable for Box<[T]> {}
+unsafe impl<T: OwnedLockable> OwnedLockable for Vec<T> {}
diff --git a/src/rwlock.rs b/src/rwlock.rs
index 7fb8c7a..40c5a6e 100644
--- a/src/rwlock.rs
+++ b/src/rwlock.rs
@@ -56,7 +56,8 @@ pub struct RwLock<T: ?Sized, R> {
/// that only read access is needed to the data.
///
/// [`LockCollection`]: `crate::LockCollection`
-pub struct ReadLock<'a, T: ?Sized, R>(&'a RwLock<T, R>);
+#[repr(transparent)]
+pub struct ReadLock<T: ?Sized, R>(RwLock<T, R>);
/// Grants write access to an [`RwLock`]
///
@@ -64,7 +65,8 @@ pub struct ReadLock<'a, T: ?Sized, R>(&'a RwLock<T, R>);
/// that write access is needed to the data.
///
/// [`LockCollection`]: `crate::LockCollection`
-pub struct WriteLock<'a, T: ?Sized, R>(&'a RwLock<T, R>);
+#[repr(transparent)]
+pub struct WriteLock<T: ?Sized, R>(RwLock<T, R>);
/// RAII structure that unlocks the shared read access to a [`RwLock`]
pub struct RwLockReadRef<'a, T: ?Sized, R: RawRwLock>(
diff --git a/src/rwlock/read_lock.rs b/src/rwlock/read_lock.rs
index 133ca7d..a8bb9be 100644
--- a/src/rwlock/read_lock.rs
+++ b/src/rwlock/read_lock.rs
@@ -6,7 +6,7 @@ use crate::key::Keyable;
use super::{ReadLock, RwLock, RwLockReadGuard, RwLockReadRef};
-impl<'a, T: ?Sized + Debug, R: RawRwLock> Debug for ReadLock<'a, T, R> {
+impl<T: ?Sized + Debug, R: RawRwLock> Debug for ReadLock<T, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// safety: this is just a try lock, and the value is dropped
// immediately after, so there's no risk of blocking ourselves
@@ -28,19 +28,19 @@ impl<'a, T: ?Sized + Debug, R: RawRwLock> Debug for ReadLock<'a, T, R> {
}
}
-impl<'a, T: ?Sized, R> From<&'a RwLock<T, R>> for ReadLock<'a, T, R> {
- fn from(value: &'a RwLock<T, R>) -> Self {
+impl<T, R> From<RwLock<T, R>> for ReadLock<T, R> {
+ fn from(value: RwLock<T, R>) -> Self {
Self::new(value)
}
}
-impl<'a, T: ?Sized, R> AsRef<RwLock<T, R>> for ReadLock<'a, T, R> {
+impl<T: ?Sized, R> AsRef<RwLock<T, R>> for ReadLock<T, R> {
fn as_ref(&self) -> &RwLock<T, R> {
- self.0
+ &self.0
}
}
-impl<'a, T: ?Sized, R> ReadLock<'a, T, R> {
+impl<T, R> ReadLock<T, R> {
/// Creates a new `ReadLock` which accesses the given [`RwLock`]
///
/// # Examples
@@ -52,12 +52,12 @@ impl<'a, T: ?Sized, R> ReadLock<'a, T, R> {
/// let read_lock = ReadLock::new(&lock);
/// ```
#[must_use]
- pub const fn new(rwlock: &'a RwLock<T, R>) -> Self {
+ pub const fn new(rwlock: RwLock<T, R>) -> Self {
Self(rwlock)
}
}
-impl<'a, T: ?Sized, R: RawRwLock> ReadLock<'a, T, R> {
+impl<T: ?Sized, R: RawRwLock> ReadLock<T, R> {
/// Locks the underlying [`RwLock`] with shared read access, blocking the
/// current thread until it can be acquired.
pub fn lock<'s, 'key: 's, Key: Keyable + 'key>(
diff --git a/src/rwlock/write_lock.rs b/src/rwlock/write_lock.rs
index c6b4c24..a344125 100644
--- a/src/rwlock/write_lock.rs
+++ b/src/rwlock/write_lock.rs
@@ -6,7 +6,7 @@ use crate::key::Keyable;
use super::{RwLock, RwLockWriteGuard, RwLockWriteRef, WriteLock};
-impl<'a, T: ?Sized + Debug, R: RawRwLock> Debug for WriteLock<'a, T, R> {
+impl<T: ?Sized + Debug, R: RawRwLock> Debug for WriteLock<T, R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// safety: this is just a try lock, and the value is dropped
// immediately after, so there's no risk of blocking ourselves
@@ -28,19 +28,19 @@ impl<'a, T: ?Sized + Debug, R: RawRwLock> Debug for WriteLock<'a, T, R> {
}
}
-impl<'a, T: ?Sized, R> From<&'a RwLock<T, R>> for WriteLock<'a, T, R> {
- fn from(value: &'a RwLock<T, R>) -> Self {
+impl<T, R> From<RwLock<T, R>> for WriteLock<T, R> {
+ fn from(value: RwLock<T, R>) -> Self {
Self::new(value)
}
}
-impl<'a, T: ?Sized, R> AsRef<RwLock<T, R>> for WriteLock<'a, T, R> {
+impl<T: ?Sized, R> AsRef<RwLock<T, R>> for WriteLock<T, R> {
fn as_ref(&self) -> &RwLock<T, R> {
- self.0
+ &self.0
}
}
-impl<'a, T: ?Sized, R> WriteLock<'a, T, R> {
+impl<T, R> WriteLock<T, R> {
/// Creates a new `WriteLock` which accesses the given [`RwLock`]
///
/// # Examples
@@ -52,12 +52,12 @@ impl<'a, T: ?Sized, R> WriteLock<'a, T, R> {
/// let write_lock = WriteLock::new(&lock);
/// ```
#[must_use]
- pub const fn new(rwlock: &'a RwLock<T, R>) -> Self {
+ pub const fn new(rwlock: RwLock<T, R>) -> Self {
Self(rwlock)
}
}
-impl<'a, T: ?Sized, R: RawRwLock> WriteLock<'a, T, R> {
+impl<T: ?Sized, R: RawRwLock> WriteLock<T, R> {
/// Locks the underlying [`RwLock`] with exclusive write access, blocking
/// the current until it can be acquired.
pub fn lock<'s, 'key: 's, Key: Keyable + 'key>(