summaryrefslogtreecommitdiff
path: root/src/context
diff options
context:
space:
mode:
Diffstat (limited to 'src/context')
-rw-r--r--src/context/context.rs6
-rw-r--r--src/context/iterator.rs7
-rw-r--r--src/context/tuple.rs8
3 files changed, 20 insertions, 1 deletions
diff --git a/src/context/context.rs b/src/context/context.rs
index adc684f..80a1881 100644
--- a/src/context/context.rs
+++ b/src/context/context.rs
@@ -7,7 +7,9 @@ use crate::{
};
impl<'l, L> LockContext<'l, L> {
- pub(crate) const fn new(lockable: &'l L) -> Self
+ /// Safety: Don't lock the locks in a different order than what the
+ /// LockContext uses
+ pub(crate) const unsafe fn new(lockable: &'l L) -> Self
where
L: OwnedLockable,
{
@@ -56,6 +58,8 @@ impl<'l, L> LockContext<'l, L> {
/// ```
///
/// [`ContextGuard`]: `crate::context::ContextGuard`
+ // The mutable reference ensures that all of the guards, which have a shared
+ // borrow to the context, must be dropped first
pub fn unlock(&mut self) -> Option<ThreadKey> {
self.key.take()
}
diff --git a/src/context/iterator.rs b/src/context/iterator.rs
index cc3bd7c..1eacaea 100644
--- a/src/context/iterator.rs
+++ b/src/context/iterator.rs
@@ -315,6 +315,7 @@ impl<'c, L: 'c + Iterator<Item = &'c I>, I: 'c + RawLock + Lockable, O> LockingI
/// let last = iter.lock_last().unwrap();
/// assert_eq!(**last, 8);
/// ```
+ // I'm honestly not sure why anyone would use this
pub fn lock_last(self) -> Option<ContextGuard<'c, <I as Lockable>::Guard<'c>, ThreadKey>> {
self.iterator.last().map(|lock| unsafe {
lock.raw_write();
@@ -542,6 +543,12 @@ impl<'c, L: 'c + Iterator<Item = &'c I>, I: 'c + RawLock + Sharable, O>
}
}
+// Most of these methods are wrappers around Iterator methods. I didn't
+// implement all of them. Some of them don't make sense for this type of
+// collection, like rposition. Many iterator methods also take closures, and I
+// wasn't sure if people would want a reference to the lock or the value inside
+// the lock. In retrospect, we can't actually allow people to see references to
+// the locks, so maybe we should just settle for values inside locks.
impl<'l, L: Iterator, O> LockingIterator<'l, L, O> {
/// Advances the iterator, without locking the next element in the iterator.
///
diff --git a/src/context/tuple.rs b/src/context/tuple.rs
index 9bca72e..d2a1b0d 100644
--- a/src/context/tuple.rs
+++ b/src/context/tuple.rs
@@ -17,6 +17,9 @@ impl<'c, A, B, O> LockingTuple<'c, A, B, O> {
}
}
+// Some day I need to invent variadic generics for Rust to make this easier for
+// myself
+
macro_rules! lock_impl {
($self: expr, $field: tt) => {
unsafe {
@@ -158,6 +161,10 @@ macro_rules! recurse_iter_impl {
};
}
+// I created these types to help reduce the complexity of the method return
+// types. But now I've added so much functionality that these types are just as
+// complicates. Oh well.
+
type LockReturn<'a, 'context, Guarded, L, C, O> = (
ContextGuard<'a, <Guarded as Lockable>::Guard<'a>, ThreadKey>,
LockingTuple<'context, L, C, O>,
@@ -185,6 +192,7 @@ type RecurseIterReturn<'context, Inner, L, C, O> = LockingIterator<
impl<T, C, Outer> LockingTuple<'_, T, C, Outer> {
/// Exit out of the current scope of the locking tuple into the parent.
+ // Luckily, this only needs one implementation
pub fn exit(self) -> Outer {
self.outer
}