summaryrefslogtreecommitdiff
path: root/src/collection/boxed.rs
diff options
context:
space:
mode:
authorMica White <botahamec@gmail.com>2024-12-25 17:58:38 -0500
committerMica White <botahamec@gmail.com>2024-12-25 22:44:03 -0500
commit311842d28d1fbb6da945f0d98f1655f77a58abf9 (patch)
tree4da3c8ab6fb3732c1ebb11306dab3799decd6b2c /src/collection/boxed.rs
parent37ab873d21ca1fcd43db8d6a26d5bac4f5285f71 (diff)
as_mut re-organization
Diffstat (limited to 'src/collection/boxed.rs')
-rw-r--r--src/collection/boxed.rs66
1 files changed, 43 insertions, 23 deletions
diff --git a/src/collection/boxed.rs b/src/collection/boxed.rs
index 3766bed..fca1db2 100644
--- a/src/collection/boxed.rs
+++ b/src/collection/boxed.rs
@@ -3,7 +3,7 @@ use std::cell::UnsafeCell;
use std::fmt::Debug;
use std::marker::PhantomData;
-use crate::lockable::{Lockable, OwnedLockable, RawLock, Sharable};
+use crate::lockable::{Lockable, LockableIntoInner, OwnedLockable, RawLock, Sharable};
use crate::Keyable;
use super::{utils, BoxedLockCollection, LockGuard};
@@ -17,7 +17,8 @@ fn contains_duplicates(l: &[&dyn RawLock]) -> bool {
}
l.windows(2)
- .any(|window| std::ptr::eq(window[0], window[1]))
+ // NOTE: addr_eq is necessary because eq would also compare the v-table pointers
+ .any(|window| std::ptr::addr_eq(window[0], window[1]))
}
unsafe impl<L: Lockable> RawLock for BoxedLockCollection<L> {
@@ -67,7 +68,7 @@ unsafe impl<L: Lockable> Lockable for BoxedLockCollection<L> {
}
unsafe fn guard(&self) -> Self::Guard<'_> {
- self.data().guard()
+ self.child().guard()
}
}
@@ -78,12 +79,20 @@ unsafe impl<L: Sharable> Sharable for BoxedLockCollection<L> {
Self: 'g;
unsafe fn read_guard(&self) -> Self::ReadGuard<'_> {
- self.data().read_guard()
+ self.child().read_guard()
}
}
unsafe impl<L: OwnedLockable> OwnedLockable for BoxedLockCollection<L> {}
+impl<L: LockableIntoInner> LockableIntoInner for BoxedLockCollection<L> {
+ type Inner = L::Inner;
+
+ fn into_inner(self) -> Self::Inner {
+ LockableIntoInner::into_inner(self.into_child())
+ }
+}
+
impl<L> IntoIterator for BoxedLockCollection<L>
where
L: IntoIterator,
@@ -92,7 +101,7 @@ where
type IntoIter = <L as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
- self.into_inner().into_iter()
+ self.into_child().into_iter()
}
}
@@ -104,7 +113,7 @@ where
type IntoIter = <&'a L as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
- self.data().into_iter()
+ self.child().into_iter()
}
}
@@ -125,16 +134,20 @@ unsafe impl<L: Sync> Sync for BoxedLockCollection<L> {}
impl<L> Drop for BoxedLockCollection<L> {
#[mutants::skip]
fn drop(&mut self) {
- self.locks.clear();
+ unsafe {
+ // safety: this collection will never be locked again
+ self.locks.clear();
+ // safety: this was allocated using a box, and is now unique
+ let boxed: Box<UnsafeCell<L>> = Box::from_raw(self.data.cast_mut());
- // safety: this was allocated using a box
- unsafe { std::alloc::dealloc(self.data.cast_mut().cast(), Layout::new::<UnsafeCell<L>>()) }
+ drop(boxed)
+ }
}
}
-impl<L> AsRef<L> for BoxedLockCollection<L> {
- fn as_ref(&self) -> &L {
- self.data()
+impl<T, L: AsRef<T>> AsRef<T> for BoxedLockCollection<L> {
+ fn as_ref(&self) -> &T {
+ self.child().as_ref()
}
}
@@ -174,17 +187,24 @@ impl<L> BoxedLockCollection<L> {
/// let lock = LockCollection::try_new(&data).unwrap();
///
/// let key = ThreadKey::get().unwrap();
- /// let guard = lock.into_inner().0.lock(key);
+ /// let guard = lock.into_child().0.lock(key);
/// assert_eq!(*guard, 42);
/// ```
#[must_use]
- pub fn into_inner(self) -> L {
- // safety: this is owned, so no other references exist
- unsafe { self.data.read().into_inner() }
+ pub fn into_child(mut self) -> L {
+ unsafe {
+ // safety: this collection will never be locked again
+ self.locks.clear();
+ // safety: this was allocated using a box, and is now unique
+ let boxed: Box<UnsafeCell<L>> = Box::from_raw(self.data.cast_mut());
+
+ boxed.into_inner()
+ }
}
/// Gets an immutable reference to the underlying data
- fn data(&self) -> &L {
+ #[must_use]
+ pub fn child(&self) -> &L {
unsafe {
self.data
.as_ref()
@@ -338,7 +358,7 @@ impl<L: Lockable> BoxedLockCollection<L> {
LockGuard {
// safety: we've already acquired the lock
- guard: self.data().guard(),
+ guard: self.child().guard(),
key,
_phantom: PhantomData,
}
@@ -361,11 +381,11 @@ impl<L: Lockable> BoxedLockCollection<L> {
/// let lock = LockCollection::new(data);
///
/// match lock.try_lock(key) {
- /// Some(mut guard) => {
+ /// Ok(mut guard) => {
/// *guard.0 += 1;
/// *guard.1 = "1";
/// },
- /// None => unreachable!(),
+ /// Err(_) => unreachable!(),
/// };
///
/// ```
@@ -379,7 +399,7 @@ impl<L: Lockable> BoxedLockCollection<L> {
}
// safety: we've acquired the locks
- self.data().guard()
+ self.child().guard()
};
Ok(LockGuard {
@@ -442,7 +462,7 @@ impl<L: Sharable> BoxedLockCollection<L> {
LockGuard {
// safety: we've already acquired the lock
- guard: self.data().read_guard(),
+ guard: self.child().read_guard(),
key,
_phantom: PhantomData,
}
@@ -485,7 +505,7 @@ impl<L: Sharable> BoxedLockCollection<L> {
}
// safety: we've acquired the locks
- self.data().read_guard()
+ self.child().read_guard()
};
Some(LockGuard {