summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMica White <botahamec@outlook.com>2026-09-13 15:12:08 -0400
committerMica White <botahamec@outlook.com>2026-09-13 15:12:08 -0400
commit16d6bd7ece4c4b9b72f6bd51c9b034270b745525 (patch)
tree4ff744fc41319ce73abe06416fabeaa7c17fbd46
parent9fd7b94cd7c20abe66cea875a0e83e76a7a00fbc (diff)
Support no_stdno-std
-rwxr-xr-xCargo.toml3
-rwxr-xr-xsrc/collection.rs4
-rwxr-xr-xsrc/collection/boxed.rs38
-rwxr-xr-xsrc/collection/guard.rs18
-rwxr-xr-xsrc/collection/owned.rs28
-rwxr-xr-xsrc/collection/ref.rs35
-rwxr-xr-xsrc/collection/retry.rs52
-rwxr-xr-xsrc/collection/utils.rs6
-rw-r--r--src/context.rs17
-rw-r--r--src/context/context.rs2
-rw-r--r--src/context/guard.rs12
-rw-r--r--src/context/iterator.rs6
-rw-r--r--src/context/tuple.rs2
-rwxr-xr-xsrc/handle_unwind.rs38
-rwxr-xr-xsrc/key.rs47
-rwxr-xr-xsrc/lib.rs3
-rwxr-xr-xsrc/lockable.rs37
-rwxr-xr-xsrc/mutex.rs13
-rwxr-xr-xsrc/mutex/guard.rs20
-rwxr-xr-xsrc/mutex/mutex.rs13
-rwxr-xr-xsrc/poisonable.rs40
-rwxr-xr-xsrc/poisonable/error.rs2
-rwxr-xr-xsrc/poisonable/flag.rs2
-rwxr-xr-xsrc/poisonable/guard.rs26
-rwxr-xr-xsrc/poisonable/poisonable.rs4
-rwxr-xr-xsrc/rwlock.rs25
-rwxr-xr-xsrc/rwlock/read_guard.rs20
-rwxr-xr-xsrc/rwlock/rwlock.rs15
-rwxr-xr-xsrc/rwlock/write_guard.rs20
-rwxr-xr-xtests/evil_mutex.rs2
-rwxr-xr-xtests/evil_rwlock.rs5
-rwxr-xr-xtests/evil_try_mutex.rs2
-rwxr-xr-xtests/evil_try_rwlock.rs2
-rwxr-xr-xtests/evil_unlock_mutex.rs2
-rwxr-xr-xtests/evil_unlock_rwlock.rs2
-rwxr-xr-xtests/forget.rs2
-rwxr-xr-xtests/retry.rs2
-rwxr-xr-xtests/retry_rw.rs2
38 files changed, 423 insertions, 146 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 1e05023..e3dec22 100755
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,7 +24,8 @@ mutants = "0.0.3" # used to skip functions that can't run
parking_lot = "0.12"
[features]
-default = ["parking_lot"]
+default = ["parking_lot", "std"]
+std = []
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ["cfg(tarpaulin_include)"] }
diff --git a/src/collection.rs b/src/collection.rs
index c97bbd2..c02e2c2 100755
--- a/src/collection.rs
+++ b/src/collection.rs
@@ -1,4 +1,6 @@
-use std::cell::UnsafeCell;
+use core::cell::UnsafeCell;
+
+use alloc::vec::Vec;
use crate::{lockable::RawLock, ThreadKey};
diff --git a/src/collection/boxed.rs b/src/collection/boxed.rs
index 66e6df0..88f3073 100755
--- a/src/collection/boxed.rs
+++ b/src/collection/boxed.rs
@@ -1,5 +1,8 @@
-use std::cell::UnsafeCell;
-use std::fmt::Debug;
+use core::cell::UnsafeCell;
+use core::fmt::Debug;
+
+use alloc::boxed::Box;
+use alloc::vec::Vec;
use crate::lockable::{Lockable, LockableIntoInner, OwnedLockable, RawLock, Sharable};
use crate::{Keyable, ThreadKey};
@@ -169,7 +172,7 @@ impl<T: ?Sized, L: AsRef<T>> AsRef<T> for BoxedLockCollection<L> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<L: Debug> Debug for BoxedLockCollection<L> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct(stringify!(BoxedLockCollection))
.field("data", &self.child)
// there's not much reason to show the sorted locks
@@ -207,11 +210,11 @@ impl<L> BoxedLockCollection<L> {
pub fn into_child(mut self) -> L {
unsafe {
// safety: this collection will never be used again
- std::ptr::drop_in_place(&raw mut self.locks);
+ core::ptr::drop_in_place(&raw mut self.locks);
// safety: this was allocated using a box, and is now unique
let boxed: Box<UnsafeCell<L>> = Box::from_raw(self.child.cast_mut());
// to prevent a double free
- std::mem::forget(self);
+ core::mem::forget(self);
boxed.into_inner()
}
@@ -327,7 +330,7 @@ impl<L: Lockable> BoxedLockCollection<L> {
locks.sort_by_key(|lock| (&raw const **lock).cast::<()>() as usize);
// safety: we're just changing the lifetimes
- let locks: Vec<&'static dyn RawLock> = unsafe { std::mem::transmute(locks) };
+ let locks: Vec<&'static dyn RawLock> = unsafe { core::mem::transmute(locks) };
let data = &raw const *data;
Self { child: data, locks }
}
@@ -770,9 +773,12 @@ where
#[cfg(test)]
mod tests {
use super::*;
- use crate::{Mutex, RwLock, ThreadKey};
+ use crate::Mutex;
+ #[cfg(feature = "std")]
+ use crate::{RwLock, ThreadKey};
#[test]
+ #[cfg(feature = "std")]
fn from_iterator() {
let key = ThreadKey::get().unwrap();
let collection: BoxedLockCollection<Vec<Mutex<&str>>> =
@@ -786,6 +792,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn from() {
let key = ThreadKey::get().unwrap();
let collection =
@@ -805,6 +812,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn into_ref_iterator() {
let mut key = ThreadKey::get().unwrap();
let collection = BoxedLockCollection::new([Mutex::new(0), Mutex::new(1), Mutex::new(2)]);
@@ -814,6 +822,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn ref_iterator() {
let mut key = ThreadKey::get().unwrap();
let collection = BoxedLockCollection::new([Mutex::new(0), Mutex::new(1), Mutex::new(2)]);
@@ -847,6 +856,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_read_sees_changes() {
let mut key = ThreadKey::get().unwrap();
let mutexes = [RwLock::new(24), RwLock::new(42)];
@@ -863,6 +873,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_try_lock_can_fail() {
let key = ThreadKey::get().unwrap();
let collection = BoxedLockCollection::new([Mutex::new(1), Mutex::new(2)]);
@@ -880,6 +891,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_try_read_can_fail() {
let key = ThreadKey::get().unwrap();
let collection = BoxedLockCollection::new([RwLock::new(1), RwLock::new(2)]);
@@ -897,6 +909,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_lock_works() {
let key = ThreadKey::get().unwrap();
let collection = BoxedLockCollection::new([Mutex::new(1), Mutex::new(2)]);
@@ -914,6 +927,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_read_works() {
let key = ThreadKey::get().unwrap();
let collection = BoxedLockCollection::new([RwLock::new(1), RwLock::new(2)]);
@@ -931,6 +945,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_lock_fails_with_one_exclusive_lock() {
let key = ThreadKey::get().unwrap();
let locks = [Mutex::new(1), Mutex::new(2)];
@@ -949,6 +964,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_read_fails_during_exclusive_lock() {
let key = ThreadKey::get().unwrap();
let collection = BoxedLockCollection::new([RwLock::new(1), RwLock::new(2)]);
@@ -966,6 +982,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_read_fails_with_one_exclusive_lock() {
let key = ThreadKey::get().unwrap();
let locks = [RwLock::new(1), RwLock::new(2)];
@@ -984,6 +1001,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn unlock_collection_works() {
let key = ThreadKey::get().unwrap();
let mutex1 = Mutex::new("foo");
@@ -996,6 +1014,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn read_unlock_collection_works() {
let key = ThreadKey::get().unwrap();
let lock1 = RwLock::new("foo");
@@ -1014,6 +1033,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn works_in_collection() {
let key = ThreadKey::get().unwrap();
let mutex1 = RwLock::new(0);
@@ -1043,7 +1063,7 @@ mod tests {
let mutexes = [Mutex::new(0), Mutex::new(1)];
let collection = BoxedLockCollection::new_ref(&mutexes);
- assert!(std::ptr::addr_eq(&raw const mutexes, collection.as_ref()))
+ assert!(core::ptr::addr_eq(&raw const mutexes, collection.as_ref()))
}
#[test]
@@ -1051,6 +1071,6 @@ mod tests {
let mutexes = [Mutex::new(0), Mutex::new(1)];
let collection = BoxedLockCollection::new_ref(&mutexes);
- assert!(std::ptr::addr_eq(&raw const mutexes, *collection.child()))
+ assert!(core::ptr::addr_eq(&raw const mutexes, *collection.child()))
}
}
diff --git a/src/collection/guard.rs b/src/collection/guard.rs
index ab66ffe..a9bf66e 100755
--- a/src/collection/guard.rs
+++ b/src/collection/guard.rs
@@ -1,13 +1,13 @@
-use std::fmt::{Debug, Display};
-use std::hash::Hash;
-use std::ops::{Deref, DerefMut};
+use core::fmt::{Debug, Display};
+use core::hash::Hash;
+use core::ops::{Deref, DerefMut};
use super::LockGuard;
#[mutants::skip] // hashing involves RNG and is hard to test
#[cfg(not(tarpaulin_include))]
impl<Guard: Hash> Hash for LockGuard<Guard> {
- fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.guard.hash(state)
}
}
@@ -20,13 +20,13 @@ impl<Guard: Hash> Hash for LockGuard<Guard> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<Guard: Debug> Debug for LockGuard<Guard> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Debug::fmt(&**self, f)
}
}
impl<Guard: Display> Display for LockGuard<Guard> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Display::fmt(&**self, f)
}
}
@@ -59,10 +59,13 @@ impl<Guard> AsMut<Guard> for LockGuard<Guard> {
#[cfg(test)]
mod tests {
+ #[cfg(feature = "std")]
use crate::collection::OwnedLockCollection;
+ #[cfg(feature = "std")]
use crate::{LockCollection, Mutex, RwLock, ThreadKey};
#[test]
+ #[cfg(feature = "std")]
fn guard_display_works() {
let key = ThreadKey::get().unwrap();
let lock = OwnedLockCollection::new(RwLock::new("Hello, world!"));
@@ -71,6 +74,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn deref_mut_works() {
let key = ThreadKey::get().unwrap();
let locks = (Mutex::new(1), Mutex::new(2));
@@ -88,6 +92,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn as_ref_works() {
let key = ThreadKey::get().unwrap();
let locks = (Mutex::new(1), Mutex::new(2));
@@ -105,6 +110,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn as_mut_works() {
let key = ThreadKey::get().unwrap();
let locks = (Mutex::new(1), Mutex::new(2));
diff --git a/src/collection/owned.rs b/src/collection/owned.rs
index ab45e86..e53feb7 100755
--- a/src/collection/owned.rs
+++ b/src/collection/owned.rs
@@ -1,3 +1,5 @@
+use alloc::vec::Vec;
+
use crate::context::LockContext;
use crate::lockable::{
Lockable, LockableGetMut, LockableIntoInner, OwnedLockable, RawLock, Sharable,
@@ -676,10 +678,15 @@ impl<L: LockableIntoInner> OwnedLockCollection<L> {
#[cfg(test)]
mod tests {
+ use alloc::{string::String, vec};
+
use super::*;
- use crate::{LockCollection, Mutex, RwLock, ThreadKey};
+ use crate::{LockCollection, Mutex};
+ #[cfg(feature = "std")]
+ use crate::{RwLock, ThreadKey};
#[test]
+ #[cfg(feature = "std")]
fn get_mut_applies_changes() {
let key = ThreadKey::get().unwrap();
let mut collection = OwnedLockCollection::new([Mutex::new("foo"), Mutex::new("bar")]);
@@ -693,6 +700,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn into_inner_works() {
let key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::from([Mutex::new("foo")]);
@@ -727,6 +735,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_read_works() {
let mut key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new([RwLock::new(24), RwLock::new(42)]);
@@ -735,6 +744,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_lock_works() {
let mut key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new([RwLock::new(24), RwLock::new(42)]);
@@ -750,6 +760,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_try_lock_can_fail() {
let key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new([Mutex::new(1), Mutex::new(2)]);
@@ -767,6 +778,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_try_read_can_fail() {
let key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new([RwLock::new(1), RwLock::new(2)]);
@@ -784,6 +796,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_lock_works_on_unlocked() {
let key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new((Mutex::new(0), Mutex::new(1)));
@@ -793,6 +806,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_lock_fails_on_locked() {
let key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new((Mutex::new(0), Mutex::new(1)));
@@ -801,7 +815,7 @@ mod tests {
s.spawn(|| {
let key = ThreadKey::get().unwrap();
let guard = collection.lock(key);
- std::mem::forget(guard);
+ core::mem::forget(guard);
});
});
@@ -809,6 +823,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_read_succeeds_for_unlocked_collection() {
let key = ThreadKey::get().unwrap();
let mutexes = [RwLock::new(24), RwLock::new(42)];
@@ -819,6 +834,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_read_fails_on_locked() {
let key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new((RwLock::new(0), RwLock::new(1)));
@@ -827,7 +843,7 @@ mod tests {
s.spawn(|| {
let key = ThreadKey::get().unwrap();
let guard = collection.lock(key);
- std::mem::forget(guard);
+ core::mem::forget(guard);
});
});
@@ -835,6 +851,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn can_read_twice_on_different_threads() {
let key = ThreadKey::get().unwrap();
let mutexes = [RwLock::new(24), RwLock::new(42)];
@@ -846,7 +863,7 @@ mod tests {
let guard = collection.read(key);
assert_eq!(*guard[0], 24);
assert_eq!(*guard[1], 42);
- std::mem::forget(guard);
+ core::mem::forget(guard);
});
});
@@ -856,6 +873,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn unlock_collection_works() {
let key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new((Mutex::new("foo"), Mutex::new("bar")));
@@ -866,6 +884,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn read_unlock_collection_works() {
let key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new((RwLock::new("foo"), RwLock::new("bar")));
@@ -897,6 +916,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn works_in_collection() {
let key = ThreadKey::get().unwrap();
let collection =
diff --git a/src/collection/ref.rs b/src/collection/ref.rs
index a422bb2..8ab7120 100755
--- a/src/collection/ref.rs
+++ b/src/collection/ref.rs
@@ -1,4 +1,6 @@
-use std::fmt::Debug;
+use core::fmt::Debug;
+
+use alloc::vec::Vec;
use crate::lockable::{Lockable, OwnedLockable, RawLock, Sharable};
use crate::{Keyable, ThreadKey};
@@ -114,7 +116,7 @@ impl<T: ?Sized, L: AsRef<T>> AsRef<T> for RefLockCollection<'_, L> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<L: Debug> Debug for RefLockCollection<'_, L> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct(stringify!(RefLockCollection))
.field("data", self.child)
// there's not much reason to show the sorting order
@@ -640,7 +642,9 @@ where
#[cfg(test)]
mod tests {
use super::*;
- use crate::{Mutex, RwLock, ThreadKey};
+ use crate::Mutex;
+ #[cfg(feature = "std")]
+ use crate::{RwLock, ThreadKey};
#[test]
fn non_duplicates_allowed() {
@@ -656,6 +660,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn from() {
let key = ThreadKey::get().unwrap();
let mutexes = [Mutex::new("foo"), Mutex::new("bar"), Mutex::new("baz")];
@@ -667,6 +672,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_lock_changes_collection() {
let mut key = ThreadKey::get().unwrap();
let mutexes = [Mutex::new(24), Mutex::new(42)];
@@ -684,6 +690,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_read_sees_changes() {
let mut key = ThreadKey::get().unwrap();
let mutexes = [RwLock::new(24), RwLock::new(42)];
@@ -702,6 +709,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_try_lock_can_fail() {
let key = ThreadKey::get().unwrap();
let locks = [Mutex::new(1), Mutex::new(2)];
@@ -720,6 +728,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_try_read_can_fail() {
let key = ThreadKey::get().unwrap();
let locks = [RwLock::new(1), RwLock::new(2)];
@@ -738,6 +747,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_lock_succeeds_for_unlocked_collection() {
let key = ThreadKey::get().unwrap();
let mutexes = [Mutex::new(24), Mutex::new(42)];
@@ -748,6 +758,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_lock_fails_for_locked_collection() {
let key = ThreadKey::get().unwrap();
let mutexes = [Mutex::new(24), Mutex::new(42)];
@@ -758,7 +769,7 @@ mod tests {
let key = ThreadKey::get().unwrap();
let guard = mutexes[1].lock(key);
assert_eq!(*guard, 42);
- std::mem::forget(guard);
+ core::mem::forget(guard);
});
});
@@ -767,6 +778,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_read_succeeds_for_unlocked_collection() {
let key = ThreadKey::get().unwrap();
let mutexes = [RwLock::new(24), RwLock::new(42)];
@@ -777,6 +789,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_read_fails_for_locked_collection() {
let key = ThreadKey::get().unwrap();
let mutexes = [RwLock::new(24), RwLock::new(42)];
@@ -787,7 +800,7 @@ mod tests {
let key = ThreadKey::get().unwrap();
let guard = mutexes[1].write(key);
assert_eq!(*guard, 42);
- std::mem::forget(guard);
+ core::mem::forget(guard);
});
});
@@ -796,6 +809,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn can_read_twice_on_different_threads() {
let key = ThreadKey::get().unwrap();
let mutexes = [RwLock::new(24), RwLock::new(42)];
@@ -807,7 +821,7 @@ mod tests {
let guard = collection.read(key);
assert_eq!(*guard[0], 24);
assert_eq!(*guard[1], 42);
- std::mem::forget(guard);
+ core::mem::forget(guard);
});
});
@@ -817,6 +831,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn into_ref_iterator() {
let mut key = ThreadKey::get().unwrap();
let mutexes = [Mutex::new(0), Mutex::new(1), Mutex::new(2)];
@@ -827,6 +842,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn ref_iterator() {
let mut key = ThreadKey::get().unwrap();
let mutexes = [Mutex::new(0), Mutex::new(1), Mutex::new(2)];
@@ -837,6 +853,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn works_in_collection() {
let key = ThreadKey::get().unwrap();
let mutex1 = RwLock::new(0);
@@ -862,6 +879,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn unlock_collection_works() {
let key = ThreadKey::get().unwrap();
let mutexes = (Mutex::new("foo"), Mutex::new("bar"));
@@ -873,6 +891,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn read_unlock_collection_works() {
let key = ThreadKey::get().unwrap();
let locks = (RwLock::new("foo"), RwLock::new("bar"));
@@ -888,7 +907,7 @@ mod tests {
let mutexes = [Mutex::new(0), Mutex::new(1)];
let collection = RefLockCollection::new(&mutexes);
- assert!(std::ptr::addr_eq(&raw const mutexes, collection.as_ref()))
+ assert!(core::ptr::addr_eq(&raw const mutexes, collection.as_ref()))
}
#[test]
@@ -896,6 +915,6 @@ mod tests {
let mutexes = [Mutex::new(0), Mutex::new(1)];
let collection = RefLockCollection::new(&mutexes);
- assert!(std::ptr::addr_eq(&raw const mutexes, collection.child()))
+ assert!(core::ptr::addr_eq(&raw const mutexes, collection.child()))
}
}
diff --git a/src/collection/retry.rs b/src/collection/retry.rs
index b9ac530..1cce663 100755
--- a/src/collection/retry.rs
+++ b/src/collection/retry.rs
@@ -1,5 +1,6 @@
-use std::cell::Cell;
-use std::collections::HashSet;
+use core::cell::Cell;
+
+use alloc::vec::Vec;
use crate::collection::utils;
use crate::handle_unwind::handle_unwind;
@@ -14,6 +15,20 @@ use super::utils::{
};
use super::{LockGuard, RetryingLockCollection};
+cfg_select! {
+ feature = "std" => {
+ fn set_with_capacity<T>(capacity: usize) -> std::collections::HashSet<T> {
+ std::collections::HashSet::with_capacity(capacity)
+ }
+ },
+ _ => {
+ #[expect(clippy::missing_const_for_fn)]
+ fn set_with_capacity<T>(_capacity: usize) -> alloc::collections::btree_set::BTreeSet<T> {
+ alloc::collections::btree_set::BTreeSet::new()
+ }
+ },
+}
+
/// Checks that a collection contains no duplicate references to a lock.
fn contains_duplicates<L: Lockable>(data: L) -> bool {
let mut locks = Vec::new();
@@ -21,7 +36,7 @@ fn contains_duplicates<L: Lockable>(data: L) -> bool {
// cast to *const () so that the v-table pointers are not used for hashing
let locks = locks.into_iter().map(|l| (&raw const *l).cast::<()>());
- let mut locks_set = HashSet::with_capacity(locks.len());
+ let mut locks_set = set_with_capacity(locks.len());
for lock in locks {
if !locks_set.insert(lock) {
return true;
@@ -1004,9 +1019,14 @@ where
#[cfg(test)]
mod tests {
+ use alloc::vec;
+
use super::*;
+ #[cfg(feature = "std")]
use crate::collection::BoxedLockCollection;
- use crate::{Mutex, RwLock, ThreadKey};
+ #[cfg(feature = "std")]
+ use crate::ThreadKey;
+ use crate::{Mutex, RwLock};
#[test]
fn nonduplicate_lock_references_are_allowed() {
@@ -1033,6 +1053,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn from() {
let key = ThreadKey::get().unwrap();
let collection =
@@ -1044,6 +1065,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn new_ref_works() {
let key = ThreadKey::get().unwrap();
let mutexes = [Mutex::new(0), Mutex::new(1)];
@@ -1055,6 +1077,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_read_sees_changes() {
let mut key = ThreadKey::get().unwrap();
let mutexes = [RwLock::new(24), RwLock::new(42)];
@@ -1071,6 +1094,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn get_mut_affects_scoped_read() {
let mut key = ThreadKey::get().unwrap();
let mutexes = [RwLock::new(24), RwLock::new(42)];
@@ -1088,6 +1112,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_try_lock_can_fail() {
let key = ThreadKey::get().unwrap();
let collection = RetryingLockCollection::new([Mutex::new(1), Mutex::new(2)]);
@@ -1105,6 +1130,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_try_read_can_fail() {
let key = ThreadKey::get().unwrap();
let collection = RetryingLockCollection::new([RwLock::new(1), RwLock::new(2)]);
@@ -1122,6 +1148,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_lock_works() {
let key = ThreadKey::get().unwrap();
let collection = RetryingLockCollection::new([Mutex::new(1), Mutex::new(2)]);
@@ -1139,6 +1166,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_read_works() {
let key = ThreadKey::get().unwrap();
let collection = RetryingLockCollection::new([RwLock::new(1), RwLock::new(2)]);
@@ -1156,6 +1184,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_read_fails_for_locked_collection() {
let key = ThreadKey::get().unwrap();
let mutexes = [RwLock::new(24), RwLock::new(42)];
@@ -1166,7 +1195,7 @@ mod tests {
let key = ThreadKey::get().unwrap();
let guard = mutexes[1].write(key);
assert_eq!(*guard, 42);
- std::mem::forget(guard);
+ core::mem::forget(guard);
});
});
@@ -1175,6 +1204,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn locks_all_inner_mutexes() {
let key = ThreadKey::get().unwrap();
let mutex1 = Mutex::new(0);
@@ -1190,6 +1220,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn locks_all_inner_rwlocks() {
let key = ThreadKey::get().unwrap();
let rwlock1 = RwLock::new(0);
@@ -1205,6 +1236,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn works_with_other_collections() {
let key = ThreadKey::get().unwrap();
let mutex1 = Mutex::new(0);
@@ -1222,6 +1254,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn from_iterator() {
let key = ThreadKey::get().unwrap();
let collection: RetryingLockCollection<Vec<Mutex<&str>>> =
@@ -1243,6 +1276,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn into_ref_iterator() {
let mut key = ThreadKey::get().unwrap();
let collection = RetryingLockCollection::new([Mutex::new(0), Mutex::new(1), Mutex::new(2)]);
@@ -1252,6 +1286,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn ref_iterator() {
let mut key = ThreadKey::get().unwrap();
let collection = RetryingLockCollection::new([Mutex::new(0), Mutex::new(1), Mutex::new(2)]);
@@ -1261,6 +1296,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn mut_iterator() {
let mut key = ThreadKey::get().unwrap();
let mut collection =
@@ -1282,6 +1318,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn lock_empty_lock_collection() {
let key = ThreadKey::get().unwrap();
let collection: RetryingLockCollection<[RwLock<i32>; 0]> = RetryingLockCollection::new([]);
@@ -1295,6 +1332,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn read_empty_lock_collection() {
let key = ThreadKey::get().unwrap();
let collection: RetryingLockCollection<[RwLock<i32>; 0]> = RetryingLockCollection::new([]);
@@ -1312,7 +1350,7 @@ mod tests {
let mutexes = [Mutex::new(0), Mutex::new(1)];
let collection = RetryingLockCollection::new_ref(&mutexes);
- assert!(std::ptr::addr_eq(&raw const mutexes, collection.as_ref()))
+ assert!(core::ptr::addr_eq(&raw const mutexes, collection.as_ref()))
}
#[test]
@@ -1330,7 +1368,7 @@ mod tests {
let mutexes = [Mutex::new(0), Mutex::new(1)];
let collection = RetryingLockCollection::new_ref(&mutexes);
- assert!(std::ptr::addr_eq(&raw const mutexes, *collection.child()))
+ assert!(core::ptr::addr_eq(&raw const mutexes, *collection.child()))
}
#[test]
diff --git a/src/collection/utils.rs b/src/collection/utils.rs
index e79b78b..236853c 100755
--- a/src/collection/utils.rs
+++ b/src/collection/utils.rs
@@ -1,4 +1,6 @@
-use std::cell::Cell;
+use core::cell::Cell;
+
+use alloc::vec::Vec;
use crate::handle_unwind::handle_unwind;
use crate::lockable::{Lockable, RawLock, Sharable};
@@ -32,7 +34,7 @@ pub fn ordered_contains_duplicates(l: &[&dyn RawLock]) -> bool {
l.windows(2)
// NOTE: addr_eq is necessary because eq would also compare the v-table pointers
- .any(|window| std::ptr::addr_eq(window[0], window[1]))
+ .any(|window| core::ptr::addr_eq(window[0], window[1]))
}
/// Lock a set of locks in the given order. It's UB to call this without a `ThreadKey`
diff --git a/src/context.rs b/src/context.rs
index 1707022..12564f1 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -1,4 +1,4 @@
-use std::marker::PhantomData;
+use core::marker::PhantomData;
use crate::ThreadKey;
@@ -183,12 +183,14 @@ pub struct ContextGuard<'a, Guard, Key> {
#[cfg(test)]
mod tests {
+ #[cfg(feature = "std")]
use crate::{
collection::OwnedLockCollection, context::iterator::TryLockNextError, Mutex, RwLock,
ThreadKey,
};
#[test]
+ #[cfg(feature = "std")]
fn display_works_for_guard() {
let key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new((Mutex::new("Hello, world!"),));
@@ -199,6 +201,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_lock_mut_works_single_element_tuple() {
let key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new((RwLock::new(42),));
@@ -235,6 +238,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_lock_mut_works_double_element_tuple() {
let key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new((RwLock::new(42), RwLock::new(67)));
@@ -300,6 +304,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_lock_mut_works_triple_element_tuple() {
let key = ThreadKey::get().unwrap();
let collection = OwnedLockCollection::new((RwLock::new(1), RwLock::new(2), RwLock::new(3)));
@@ -393,6 +398,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn basic_iteration() {
let key = ThreadKey::get().unwrap();
let data = [Mutex::new(1), Mutex::new(3), Mutex::new(8)];
@@ -410,6 +416,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn recurse_tuple_of_lists() {
let key = ThreadKey::get().unwrap();
let data = (
@@ -435,6 +442,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn recurse_list_of_lists() {
let key = ThreadKey::get().unwrap();
let data = [
@@ -465,6 +473,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn recurse_last_list_of_lists() {
let key = ThreadKey::get().unwrap();
let data = [
@@ -486,6 +495,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn recurse_last_list_of_empty_list() {
let key = ThreadKey::get().unwrap();
let data: [[Mutex<i32>; 0]; 0] = [];
@@ -498,6 +508,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn recurse_list_of_tuples() {
let key = ThreadKey::get().unwrap();
let data = [
@@ -534,6 +545,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn recurse_last_list_of_tuples() {
let key = ThreadKey::get().unwrap();
let data = [
@@ -556,6 +568,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn recurse_last_of_empty_list_of_tuples() {
let key = ThreadKey::get().unwrap();
let data: [(Mutex<bool>, Mutex<i32>); 0] = [];
@@ -568,6 +581,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn lock_last_of_list() {
let key = ThreadKey::get().unwrap();
let data = [Mutex::new(1), Mutex::new(3), Mutex::new(8)];
@@ -579,6 +593,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_lock_next_works() {
let key = ThreadKey::get().unwrap();
let data = [Mutex::new(1), Mutex::new(3), Mutex::new(8)];
diff --git a/src/context/context.rs b/src/context/context.rs
index f67d686..67ee6d9 100644
--- a/src/context/context.rs
+++ b/src/context/context.rs
@@ -1,4 +1,4 @@
-use std::marker::PhantomData;
+use core::marker::PhantomData;
use crate::{
context::{LockContext, LockingIterator, LockingTuple},
diff --git a/src/context/guard.rs b/src/context/guard.rs
index 0898c1f..6cd80ed 100644
--- a/src/context/guard.rs
+++ b/src/context/guard.rs
@@ -1,13 +1,13 @@
-use std::fmt::{Debug, Display};
-use std::hash::Hash;
-use std::ops::{Deref, DerefMut};
+use core::fmt::{Debug, Display};
+use core::hash::Hash;
+use core::ops::{Deref, DerefMut};
use super::ContextGuard;
#[mutants::skip] // hashing involves RNG and is hard to test
#[cfg(not(tarpaulin_include))]
impl<Guard: Hash, Key> Hash for ContextGuard<'_, Guard, Key> {
- fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.guard.hash(state)
}
}
@@ -20,13 +20,13 @@ impl<Guard: Hash, Key> Hash for ContextGuard<'_, Guard, Key> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<Guard: Debug, Key> Debug for ContextGuard<'_, Guard, Key> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Debug::fmt(&**self, f)
}
}
impl<Guard: Display, Key> Display for ContextGuard<'_, Guard, Key> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Display::fmt(&**self, f)
}
}
diff --git a/src/context/iterator.rs b/src/context/iterator.rs
index 1eacaea..d7f7287 100644
--- a/src/context/iterator.rs
+++ b/src/context/iterator.rs
@@ -1,7 +1,5 @@
-use std::{
- iter::{Fuse, Peekable, Skip, Take},
- marker::PhantomData,
-};
+use core::iter::{Fuse, Peekable, Skip, Take};
+use core::marker::PhantomData;
use super::{ContextGuard, LockingIterator};
diff --git a/src/context/tuple.rs b/src/context/tuple.rs
index d2a1b0d..65d372a 100644
--- a/src/context/tuple.rs
+++ b/src/context/tuple.rs
@@ -1,4 +1,4 @@
-use std::marker::PhantomData;
+use core::marker::PhantomData;
use crate::{
context::{ContextGuard, LockingIterator, LockingTuple},
diff --git a/src/handle_unwind.rs b/src/handle_unwind.rs
index 42b6fc5..e00bbbd 100755
--- a/src/handle_unwind.rs
+++ b/src/handle_unwind.rs
@@ -1,13 +1,31 @@
+#[cfg(feature = "std")]
use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
-/// Runs `try_fn`. If it unwinds, it will run `catch` and then continue
-/// unwinding. This is used instead of `scopeguard` to ensure the `catch`
-/// function doesn't run if the thread is already panicking. The unwind
-/// must specifically be caused by the `try_fn`
-pub fn handle_unwind<R, F: FnOnce() -> R, G: FnOnce()>(try_fn: F, catch: G) -> R {
- let try_fn = AssertUnwindSafe(try_fn);
- catch_unwind(try_fn).unwrap_or_else(|e| {
- catch();
- resume_unwind(e)
- })
+cfg_select! {
+ feature = "std" => {
+ /// Runs `try_fn`. If it unwinds, it will run `catch` and then continue
+ /// unwinding. This is used instead of `scopeguard` to ensure the `catch`
+ /// function doesn't run if the thread is already panicking. The unwind
+ /// must specifically be caused by the `try_fn`
+ ///
+ /// This has no effect in `no_std` environments
+ pub fn handle_unwind<R, F: FnOnce() -> R, G: FnOnce()>(try_fn: F, catch: G) -> R {
+ let try_fn = AssertUnwindSafe(try_fn);
+ catch_unwind(try_fn).unwrap_or_else(|e| {
+ catch();
+ resume_unwind(e)
+ })
+ }
+ }
+ _ => {
+ /// Runs `try_fn`. If it unwinds, it will run `catch` and then continue
+ /// unwinding. This is used instead of `scopeguard` to ensure the `catch`
+ /// function doesn't run if the thread is already panicking. The unwind
+ /// must specifically be caused by the `try_fn`
+ ///
+ /// This has no effect in `no_std` environments
+ pub fn handle_unwind<R, F: FnOnce() -> R, G: FnOnce()>(try_fn: F, _catch: G) -> R {
+ try_fn()
+ }
+ }
}
diff --git a/src/key.rs b/src/key.rs
index c788b32..06f219b 100755
--- a/src/key.rs
+++ b/src/key.rs
@@ -1,6 +1,7 @@
-use std::cell::{Cell, LazyCell};
-use std::fmt::{self, Debug};
-use std::marker::PhantomData;
+#[cfg(feature = "std")]
+use core::cell::Cell;
+use core::fmt::{self, Debug};
+use core::marker::PhantomData;
use sealed::Sealed;
@@ -14,8 +15,9 @@ mod sealed {
impl Sealed for &mut ThreadKey {}
}
+#[cfg(feature = "std")]
thread_local! {
- static KEY: LazyCell<KeyCell> = LazyCell::new(KeyCell::default);
+ static KEY: std::cell::LazyCell<KeyCell> = std::cell::LazyCell::new(KeyCell::default);
}
/// The key for the current thread.
@@ -55,7 +57,10 @@ impl Drop for ThreadKey {
fn drop(&mut self) {
// safety: a thread key cannot be acquired without creating the lock
// safety: the key is lost, so it's safe to unlock the cell
- unsafe { KEY.with(|key| key.force_unlock()) }
+ #[cfg(feature = "std")]
+ unsafe {
+ KEY.with(|key| key.force_unlock())
+ }
}
}
@@ -74,6 +79,7 @@ impl ThreadKey {
/// let key = ThreadKey::get().unwrap();
/// ```
#[must_use]
+ #[cfg(feature = "std")]
pub fn get() -> Option<Self> {
// if this code changes, check to ensure the requirement for
// the Drop implementation is still true
@@ -83,14 +89,41 @@ impl ThreadKey {
})
})
}
+
+ /// Create a `ThreadKey` for the current thread, without checking to see if it
+ /// has already been acquired.
+ ///
+ /// This can be useful for `no_std` environments, where it's not possible to
+ /// check if the current thread has acquired a `ThreadKey`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use happylock::ThreadKey;
+ ///
+ /// let key = ThreadKey::get().unwrap();
+ /// ```
+ ///
+ /// # Safety
+ ///
+ /// This is unsafe because it allows a thread to have multiple keys at a time.
+ /// Each thread must have no more than one `ThreadKey` at a time.
+ #[must_use]
+ pub const unsafe fn get_unchecked() -> Self {
+ Self {
+ phantom: PhantomData,
+ }
+ }
}
/// A dumb lock that's just a wrapper for an [`AtomicBool`].
#[derive(Default)]
+#[cfg(feature = "std")]
struct KeyCell {
is_locked: Cell<bool>,
}
+#[cfg(feature = "std")]
impl KeyCell {
/// Attempt to lock the `KeyCell`. This is not a fair lock.
#[must_use]
@@ -107,14 +140,17 @@ impl KeyCell {
#[cfg(test)]
mod tests {
+ #[cfg(feature = "std")]
use super::*;
#[test]
+ #[cfg(feature = "std")]
fn thread_key_returns_some_on_first_call() {
assert!(ThreadKey::get().is_some());
}
#[test]
+ #[cfg(feature = "std")]
fn thread_key_returns_none_on_second_call() {
let key = ThreadKey::get();
assert!(ThreadKey::get().is_none());
@@ -122,6 +158,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn dropping_thread_key_allows_reobtaining() {
drop(ThreadKey::get());
assert!(ThreadKey::get().is_some())
diff --git a/src/lib.rs b/src/lib.rs
index e6e5e4c..2dbccfa 100755
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,4 @@
+#![cfg_attr(not(feature = "std"), no_std)]
#![warn(clippy::pedantic)]
#![warn(clippy::nursery)]
#![warn(clippy::cargo)]
@@ -194,6 +195,8 @@
//! [`OwnedLockCollection`]: `collection::OwnedLockCollection`
//! [`RetryingLockCollection`]: `collection::RetryingLockCollection`
+extern crate alloc;
+
mod handle_unwind;
mod key;
diff --git a/src/lockable.rs b/src/lockable.rs
index 705887f..e7f7f0a 100755
--- a/src/lockable.rs
+++ b/src/lockable.rs
@@ -1,4 +1,6 @@
-use std::mem::MaybeUninit;
+use core::mem::MaybeUninit;
+
+use alloc::{boxed::Box, vec::Vec};
/// A raw lock type that may be locked and unlocked
///
@@ -662,8 +664,12 @@ unsafe impl<T: OwnedLockable> OwnedLockable for Vec<T> {}
#[cfg(test)]
mod tests {
+ use alloc::vec;
+
use super::*;
- use crate::{LockCollection, Mutex, RwLock, ThreadKey};
+ #[cfg(feature = "std")]
+ use crate::{LockCollection, ThreadKey};
+ use crate::{Mutex, RwLock};
#[test]
fn mut_ref_get_ptrs() {
@@ -673,7 +679,7 @@ mod tests {
mutref.get_ptrs(&mut lock_ptrs);
assert_eq!(lock_ptrs.len(), 1);
- assert!(std::ptr::addr_eq(lock_ptrs[0], mutref));
+ assert!(core::ptr::addr_eq(lock_ptrs[0], mutref));
}
#[test]
@@ -692,7 +698,7 @@ mod tests {
locks.get_ptrs(&mut lock_ptrs);
assert_eq!(lock_ptrs.len(), 1);
- unsafe { assert!(std::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) }
+ unsafe { assert!(core::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) }
}
#[test]
@@ -702,8 +708,8 @@ mod tests {
locks.get_ptrs(&mut lock_ptrs);
assert_eq!(lock_ptrs.len(), 2);
- unsafe { assert!(std::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) }
- unsafe { assert!(std::ptr::addr_eq(lock_ptrs[1], locks[1].raw())) }
+ unsafe { assert!(core::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) }
+ unsafe { assert!(core::ptr::addr_eq(lock_ptrs[1], locks[1].raw())) }
}
#[test]
@@ -722,7 +728,7 @@ mod tests {
locks.get_ptrs(&mut lock_ptrs);
assert_eq!(lock_ptrs.len(), 1);
- unsafe { assert!(std::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) }
+ unsafe { assert!(core::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) }
}
#[test]
@@ -732,8 +738,8 @@ mod tests {
locks.get_ptrs(&mut lock_ptrs);
assert_eq!(lock_ptrs.len(), 2);
- unsafe { assert!(std::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) }
- unsafe { assert!(std::ptr::addr_eq(lock_ptrs[1], locks[1].raw())) }
+ unsafe { assert!(core::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) }
+ unsafe { assert!(core::ptr::addr_eq(lock_ptrs[1], locks[1].raw())) }
}
#[test]
@@ -757,6 +763,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn vec_guard_ref() {
let key = ThreadKey::get().unwrap();
let locks = vec![RwLock::new(1), RwLock::new(2)];
@@ -774,6 +781,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn vec_data_mut() {
let mut key = ThreadKey::get().unwrap();
let mutexes = vec![Mutex::new(1), Mutex::new(2)];
@@ -791,6 +799,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn vec_data_ref() {
let mut key = ThreadKey::get().unwrap();
let mutexes = vec![RwLock::new(1), RwLock::new(2)];
@@ -823,7 +832,7 @@ mod tests {
locks.get_ptrs(&mut lock_ptrs);
assert_eq!(lock_ptrs.len(), 1);
- unsafe { assert!(std::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) }
+ unsafe { assert!(core::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) }
}
#[test]
@@ -833,8 +842,8 @@ mod tests {
locks.get_ptrs(&mut lock_ptrs);
assert_eq!(lock_ptrs.len(), 2);
- unsafe { assert!(std::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) }
- unsafe { assert!(std::ptr::addr_eq(lock_ptrs[1], locks[1].raw())) }
+ unsafe { assert!(core::ptr::addr_eq(lock_ptrs[0], locks[0].raw())) }
+ unsafe { assert!(core::ptr::addr_eq(lock_ptrs[1], locks[1].raw())) }
}
#[test]
@@ -848,6 +857,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn box_guard_mut() {
let key = ThreadKey::get().unwrap();
let x = [Mutex::new(1), Mutex::new(2)];
@@ -865,6 +875,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn box_data_mut() {
let mut key = ThreadKey::get().unwrap();
let mutexes = vec![Mutex::new(1), Mutex::new(2)].into_boxed_slice();
@@ -882,6 +893,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn box_guard_ref() {
let key = ThreadKey::get().unwrap();
let locks = [RwLock::new(1), RwLock::new(2)];
@@ -899,6 +911,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn box_data_ref() {
let mut key = ThreadKey::get().unwrap();
let mutexes = vec![RwLock::new(1), RwLock::new(2)].into_boxed_slice();
diff --git a/src/mutex.rs b/src/mutex.rs
index d7b0176..3043dfa 100755
--- a/src/mutex.rs
+++ b/src/mutex.rs
@@ -1,5 +1,5 @@
-use std::cell::UnsafeCell;
-use std::marker::PhantomData;
+use core::cell::UnsafeCell;
+use core::marker::PhantomData;
use lock_api::RawMutex;
@@ -179,6 +179,7 @@ pub struct MutexGuard<'a, T: ?Sized + 'a, R: RawMutex> {
#[cfg(test)]
mod tests {
+ #[cfg(feature = "std")]
use crate::{LockCollection, ThreadKey};
use super::*;
@@ -191,6 +192,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn locked_after_read() {
let key = ThreadKey::get().unwrap();
let lock: crate::Mutex<_> = Mutex::new("Hello, world!");
@@ -202,6 +204,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn from_works() {
let key = ThreadKey::get().unwrap();
let mutex: crate::Mutex<_> = Mutex::from("Hello, world!");
@@ -211,6 +214,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn as_mut_works() {
let key = ThreadKey::get().unwrap();
let mut mutex = crate::Mutex::from(42);
@@ -222,6 +226,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn display_works_for_guard() {
let key = ThreadKey::get().unwrap();
let mutex: crate::Mutex<_> = Mutex::new("Hello, world!");
@@ -230,6 +235,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn display_works_for_ref() {
let mutex: crate::Mutex<_> = Mutex::new("Hello, world!");
let guard = unsafe { mutex.try_lock_no_key().unwrap() };
@@ -237,6 +243,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn ref_as_mut() {
let key = ThreadKey::get().unwrap();
let collection = LockCollection::new(crate::Mutex::new(0));
@@ -252,6 +259,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn guard_as_mut() {
let key = ThreadKey::get().unwrap();
let mutex = crate::Mutex::new(0);
@@ -267,6 +275,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn dropping_guard_releases_mutex() {
let key = ThreadKey::get().unwrap();
let mutex: crate::Mutex<_> = Mutex::new("Hello, world!");
diff --git a/src/mutex/guard.rs b/src/mutex/guard.rs
index 538a08a..dad1cd7 100755
--- a/src/mutex/guard.rs
+++ b/src/mutex/guard.rs
@@ -1,7 +1,7 @@
-use std::fmt::{Debug, Display};
-use std::hash::Hash;
-use std::marker::PhantomData;
-use std::ops::{Deref, DerefMut};
+use core::fmt::{Debug, Display};
+use core::hash::Hash;
+use core::marker::PhantomData;
+use core::ops::{Deref, DerefMut};
use lock_api::RawMutex;
@@ -16,7 +16,7 @@ use super::{Mutex, MutexGuard, MutexRef};
#[mutants::skip] // hashing involves RNG and is hard to test
#[cfg(not(tarpaulin_include))]
impl<T: Hash + ?Sized, R: RawMutex> Hash for MutexRef<'_, T, R> {
- fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
@@ -24,13 +24,13 @@ impl<T: Hash + ?Sized, R: RawMutex> Hash for MutexRef<'_, T, R> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<T: Debug + ?Sized, R: RawMutex> Debug for MutexRef<'_, T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Debug::fmt(&**self, f)
}
}
impl<T: Display + ?Sized, R: RawMutex> Display for MutexRef<'_, T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Display::fmt(&**self, f)
}
}
@@ -90,7 +90,7 @@ impl<'a, T: ?Sized, R: RawMutex> MutexRef<'a, T, R> {
#[mutants::skip] // hashing involves RNG and is hard to test
#[cfg(not(tarpaulin_include))]
impl<T: Hash + ?Sized, R: RawMutex> Hash for MutexGuard<'_, T, R> {
- fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
@@ -98,13 +98,13 @@ impl<T: Hash + ?Sized, R: RawMutex> Hash for MutexGuard<'_, T, R> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<T: Debug + ?Sized, R: RawMutex> Debug for MutexGuard<'_, T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Debug::fmt(&**self, f)
}
}
impl<T: Display + ?Sized, R: RawMutex> Display for MutexGuard<'_, T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Display::fmt(&**self, f)
}
}
diff --git a/src/mutex/mutex.rs b/src/mutex/mutex.rs
index dc374aa..f6db081 100755
--- a/src/mutex/mutex.rs
+++ b/src/mutex/mutex.rs
@@ -1,8 +1,9 @@
-use std::cell::UnsafeCell;
-use std::fmt::Debug;
-use std::marker::PhantomData;
-use std::panic::AssertUnwindSafe;
+use core::cell::UnsafeCell;
+use core::fmt::Debug;
+use core::marker::PhantomData;
+use core::panic::AssertUnwindSafe;
+use alloc::vec::Vec;
use lock_api::RawMutex;
use crate::handle_unwind::handle_unwind;
@@ -147,7 +148,7 @@ impl<T, R: RawMutex> Mutex<T, R> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<T: ?Sized + Debug, R: RawMutex> Debug for Mutex<T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
// safety: this is just a try lock, and the value is dropped
// immediately after, so there's no risk of blocking ourselves
// or any other threads
@@ -157,7 +158,7 @@ impl<T: ?Sized + Debug, R: RawMutex> Debug for Mutex<T, R> {
} else {
struct LockedPlaceholder;
impl Debug for LockedPlaceholder {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("<locked>")
}
}
diff --git a/src/poisonable.rs b/src/poisonable.rs
index 8dada90..d81b876 100755
--- a/src/poisonable.rs
+++ b/src/poisonable.rs
@@ -1,5 +1,5 @@
-use std::marker::PhantomData;
-use std::sync::atomic::AtomicBool;
+use core::marker::PhantomData;
+use core::sync::atomic::AtomicBool;
use crate::ThreadKey;
@@ -68,7 +68,7 @@ pub struct Poisonable<L> {
/// [`LockCollection`]: `crate::LockCollection`
pub struct PoisonRef<'a, G> {
guard: G,
- #[cfg(panic = "unwind")]
+ #[cfg(all(feature = "std", panic = "unwind"))]
flag: &'a PoisonFlag,
_phantom: PhantomData<&'a ()>,
}
@@ -137,13 +137,19 @@ pub type TryLockPoisonableResult<'flag, G> =
#[cfg(test)]
mod tests {
+ #[cfg(feature = "std")]
use std::sync::Arc;
+ use alloc::vec::Vec;
+
use super::*;
use crate::lockable::Lockable as _;
- use crate::{LockCollection, Mutex, RwLock, ThreadKey};
+ use crate::Mutex;
+ #[cfg(feature = "std")]
+ use crate::{LockCollection, RwLock, ThreadKey};
#[test]
+ #[cfg(feature = "std")]
fn locking_poisoned_mutex_returns_error_in_collection() {
let key = ThreadKey::get().unwrap();
let mutex = LockCollection::new(Poisonable::new(Mutex::new(42)));
@@ -169,6 +175,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn locking_poisoned_rwlock_returns_error_in_collection() {
let key = ThreadKey::get().unwrap();
let mutex = LockCollection::new(Poisonable::new(RwLock::new(42)));
@@ -202,6 +209,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn non_poisoned_get_mut_is_err() {
let mut mutex = Poisonable::new(Mutex::new(42));
@@ -226,6 +234,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn poisoned_into_inner() {
let mutex = Poisonable::from(Mutex::new("foo"));
@@ -250,6 +259,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn poisoned_into_child() {
let mutex = Poisonable::from(Mutex::new("foo"));
@@ -268,6 +278,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_lock_can_poison() {
let key = ThreadKey::get().unwrap();
let mutex = Poisonable::new(Mutex::new(42));
@@ -292,6 +303,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_try_lock_can_fail() {
let key = ThreadKey::get().unwrap();
let mutex = Poisonable::new(Mutex::new(42));
@@ -309,6 +321,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_try_lock_can_succeed() {
let rwlock = Poisonable::new(RwLock::new(42));
@@ -324,6 +337,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_read_can_poison() {
let key = ThreadKey::get().unwrap();
let mutex = Poisonable::new(RwLock::new(42));
@@ -348,6 +362,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_try_read_can_fail() {
let key = ThreadKey::get().unwrap();
let rwlock = Poisonable::new(RwLock::new(42));
@@ -365,6 +380,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn scoped_try_read_can_succeed() {
let rwlock = Poisonable::new(RwLock::new(42));
@@ -380,6 +396,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn display_works() {
let key = ThreadKey::get().unwrap();
let mutex = Poisonable::new(Mutex::new("Hello, world!"));
@@ -390,6 +407,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn ref_as_ref() {
let key = ThreadKey::get().unwrap();
let collection = LockCollection::new(Poisonable::new(Mutex::new("foo")));
@@ -401,6 +419,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn ref_as_mut() {
let key = ThreadKey::get().unwrap();
let collection = LockCollection::new(Poisonable::new(Mutex::new("foo")));
@@ -418,6 +437,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn guard_as_ref() {
let key = ThreadKey::get().unwrap();
let collection = Poisonable::new(Mutex::new("foo"));
@@ -429,6 +449,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn guard_as_mut() {
let key = ThreadKey::get().unwrap();
let mutex = Poisonable::new(Mutex::new("foo"));
@@ -446,6 +467,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn deref_mut_in_collection() {
let key = ThreadKey::get().unwrap();
let collection = LockCollection::new(Poisonable::new(Mutex::new(42)));
@@ -469,10 +491,14 @@ mod tests {
poisonable.get_ptrs(&mut lock_ptrs);
assert_eq!(lock_ptrs.len(), 1);
- assert!(std::ptr::addr_eq(lock_ptrs[0], &raw const poisonable.inner));
+ assert!(core::ptr::addr_eq(
+ lock_ptrs[0],
+ &raw const poisonable.inner
+ ));
}
#[test]
+ #[cfg(feature = "std")]
fn clear_poison_for_poisoned_mutex() {
let mutex = Arc::new(Poisonable::new(Mutex::new(0)));
let c_mutex = Arc::clone(&mutex);
@@ -497,6 +523,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn clear_poison_for_poisoned_rwlock() {
let lock = Arc::new(Poisonable::new(RwLock::new(0)));
let c_mutex = Arc::clone(&lock);
@@ -522,6 +549,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn error_as_ref() {
let mutex = Poisonable::new(Mutex::new("foo"));
@@ -543,6 +571,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn error_as_mut() {
let mutex = Poisonable::new(Mutex::new("foo"));
@@ -570,6 +599,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_error_from_lock_error() {
let mutex = Poisonable::new(Mutex::new("foo"));
diff --git a/src/poisonable/error.rs b/src/poisonable/error.rs
index eed454b..b7b9206 100755
--- a/src/poisonable/error.rs
+++ b/src/poisonable/error.rs
@@ -1,5 +1,5 @@
+use core::error::Error;
use core::fmt;
-use std::error::Error;
use super::{PoisonError, PoisonGuard, TryLockPoisonableError};
diff --git a/src/poisonable/flag.rs b/src/poisonable/flag.rs
index 9186bbc..9877245 100755
--- a/src/poisonable/flag.rs
+++ b/src/poisonable/flag.rs
@@ -1,5 +1,5 @@
#[cfg(panic = "unwind")]
-use std::sync::atomic::{AtomicBool, Ordering::Relaxed};
+use core::sync::atomic::{AtomicBool, Ordering::Relaxed};
use super::PoisonFlag;
diff --git a/src/poisonable/guard.rs b/src/poisonable/guard.rs
index 32b4ee8..c4d9250 100755
--- a/src/poisonable/guard.rs
+++ b/src/poisonable/guard.rs
@@ -1,16 +1,18 @@
-use std::fmt::{Debug, Display};
-use std::hash::Hash;
-use std::marker::PhantomData;
-use std::ops::{Deref, DerefMut};
+use core::fmt::{Debug, Display};
+use core::hash::Hash;
+use core::marker::PhantomData;
+use core::ops::{Deref, DerefMut};
use super::{PoisonFlag, PoisonGuard, PoisonRef};
impl<'a, Guard> PoisonRef<'a, Guard> {
// This is used so that we don't keep accidentally adding the flag reference
+ #[allow(clippy::allow_attributes)]
+ #[allow(unused_variables)]
pub(super) const fn new(flag: &'a PoisonFlag, guard: Guard) -> Self {
Self {
guard,
- #[cfg(panic = "unwind")]
+ #[cfg(all(feature = "std", panic = "unwind"))]
flag,
_phantom: PhantomData,
}
@@ -19,7 +21,7 @@ impl<'a, Guard> PoisonRef<'a, Guard> {
impl<Guard> Drop for PoisonRef<'_, Guard> {
fn drop(&mut self) {
- #[cfg(panic = "unwind")]
+ #[cfg(all(feature = "std", panic = "unwind"))]
if std::thread::panicking() {
self.flag.poison();
}
@@ -29,7 +31,7 @@ impl<Guard> Drop for PoisonRef<'_, Guard> {
#[mutants::skip] // hashing involves RNG and is hard to test
#[cfg(not(tarpaulin_include))]
impl<Guard: Hash> Hash for PoisonRef<'_, Guard> {
- fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.guard.hash(state)
}
}
@@ -37,13 +39,13 @@ impl<Guard: Hash> Hash for PoisonRef<'_, Guard> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<Guard: Debug> Debug for PoisonRef<'_, Guard> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Debug::fmt(&**self, f)
}
}
impl<Guard: Display> Display for PoisonRef<'_, Guard> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Display::fmt(&**self, f)
}
}
@@ -77,7 +79,7 @@ impl<Guard> AsMut<Guard> for PoisonRef<'_, Guard> {
#[mutants::skip] // hashing involves RNG and is hard to test
#[cfg(not(tarpaulin_include))]
impl<Guard: Hash> Hash for PoisonGuard<'_, Guard> {
- fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.guard.hash(state)
}
}
@@ -85,13 +87,13 @@ impl<Guard: Hash> Hash for PoisonGuard<'_, Guard> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<Guard: Debug> Debug for PoisonGuard<'_, Guard> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Debug::fmt(&self.guard, f)
}
}
impl<Guard: Display> Display for PoisonGuard<'_, Guard> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Display::fmt(&self.guard, f)
}
}
diff --git a/src/poisonable/poisonable.rs b/src/poisonable/poisonable.rs
index 0134ff1..ccca07e 100755
--- a/src/poisonable/poisonable.rs
+++ b/src/poisonable/poisonable.rs
@@ -1,4 +1,6 @@
-use std::panic::{RefUnwindSafe, UnwindSafe};
+use core::panic::{RefUnwindSafe, UnwindSafe};
+
+use alloc::vec::Vec;
use crate::collection::OwnedLockCollection;
use crate::handle_unwind::handle_unwind;
diff --git a/src/rwlock.rs b/src/rwlock.rs
index fca132d..bb9785a 100755
--- a/src/rwlock.rs
+++ b/src/rwlock.rs
@@ -1,5 +1,5 @@
-use std::cell::UnsafeCell;
-use std::marker::PhantomData;
+use core::cell::UnsafeCell;
+use core::marker::PhantomData;
use lock_api::RawRwLock;
@@ -123,11 +123,14 @@ pub struct RwLockWriteGuard<'a, T: ?Sized, R: RawRwLock> {
#[cfg(test)]
mod tests {
+ #[cfg(feature = "std")]
use crate::LockCollection;
use crate::RwLock;
+ #[cfg(feature = "std")]
use crate::ThreadKey;
#[test]
+ #[cfg(feature = "std")]
fn unlocked_when_initialized() {
let key = ThreadKey::get().unwrap();
let lock: crate::RwLock<_> = RwLock::new("Hello, world!");
@@ -137,6 +140,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn locked_after_read() {
let key = ThreadKey::get().unwrap();
let lock: crate::RwLock<_> = RwLock::new("Hello, world!");
@@ -148,6 +152,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn locked_after_write() {
let key = ThreadKey::get().unwrap();
let lock: crate::RwLock<_> = RwLock::new("Hello, world!");
@@ -159,6 +164,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn locked_after_scoped_write() {
let mut key = ThreadKey::get().unwrap();
let lock = crate::RwLock::new("Hello, world!");
@@ -177,6 +183,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn get_mut_works() {
let key = ThreadKey::get().unwrap();
let mut lock = crate::RwLock::from(42);
@@ -188,6 +195,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_write_can_fail() {
let key = ThreadKey::get().unwrap();
let lock = crate::RwLock::new("Hello");
@@ -205,6 +213,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn try_read_can_fail() {
let key = ThreadKey::get().unwrap();
let lock = crate::RwLock::new("Hello");
@@ -222,6 +231,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn read_display_works() {
let key = ThreadKey::get().unwrap();
let lock: crate::RwLock<_> = RwLock::new("Hello, world!");
@@ -230,6 +240,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn write_display_works() {
let key = ThreadKey::get().unwrap();
let lock: crate::RwLock<_> = RwLock::new("Hello, world!");
@@ -238,6 +249,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn read_ref_display_works() {
let lock: crate::RwLock<_> = RwLock::new("Hello, world!");
let guard = unsafe { lock.try_read_no_key().unwrap() };
@@ -245,6 +257,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn write_ref_display_works() {
let lock: crate::RwLock<_> = RwLock::new("Hello, world!");
let guard = unsafe { lock.try_write_no_key().unwrap() };
@@ -262,6 +275,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn dropping_write_guard_releases_rwlock() {
let key = ThreadKey::get().unwrap();
let lock: crate::RwLock<_> = RwLock::new("Hello, world!");
@@ -273,6 +287,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn unlock_write() {
let key = ThreadKey::get().unwrap();
let lock = crate::RwLock::new("Hello, world");
@@ -286,6 +301,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn unlock_read() {
let key = ThreadKey::get().unwrap();
let lock = crate::RwLock::new("Hello, world");
@@ -299,6 +315,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn read_ref_as_ref() {
let key = ThreadKey::get().unwrap();
let lock = LockCollection::new(crate::RwLock::new("hi"));
@@ -308,6 +325,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn read_guard_as_ref() {
let key = ThreadKey::get().unwrap();
let lock = crate::RwLock::new("hi");
@@ -317,6 +335,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn write_ref_as_ref() {
let key = ThreadKey::get().unwrap();
let lock = LockCollection::new(crate::RwLock::new("hi"));
@@ -326,6 +345,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn write_guard_as_ref() {
let key = ThreadKey::get().unwrap();
let lock = crate::RwLock::new("hi");
@@ -335,6 +355,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "std")]
fn write_guard_as_mut() {
let key = ThreadKey::get().unwrap();
let lock = crate::RwLock::new("hi");
diff --git a/src/rwlock/read_guard.rs b/src/rwlock/read_guard.rs
index f3161f5..7ca73d1 100755
--- a/src/rwlock/read_guard.rs
+++ b/src/rwlock/read_guard.rs
@@ -1,7 +1,7 @@
-use std::fmt::{Debug, Display};
-use std::hash::Hash;
-use std::marker::PhantomData;
-use std::ops::Deref;
+use core::fmt::{Debug, Display};
+use core::hash::Hash;
+use core::marker::PhantomData;
+use core::ops::Deref;
use lock_api::RawRwLock;
@@ -16,7 +16,7 @@ use super::{RwLock, RwLockReadGuard, RwLockReadRef};
#[mutants::skip] // hashing involves PRNG and is hard to test
#[cfg(not(tarpaulin_include))]
impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockReadRef<'_, T, R> {
- fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
@@ -24,13 +24,13 @@ impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockReadRef<'_, T, R> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<T: Debug + ?Sized, R: RawRwLock> Debug for RwLockReadRef<'_, T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Debug::fmt(&**self, f)
}
}
impl<T: Display + ?Sized, R: RawRwLock> Display for RwLockReadRef<'_, T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Display::fmt(&**self, f)
}
}
@@ -72,7 +72,7 @@ impl<'a, T: ?Sized, R: RawRwLock> RwLockReadRef<'a, T, R> {
#[mutants::skip] // hashing involves PRNG and is hard to test
#[cfg(not(tarpaulin_include))]
impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockReadGuard<'_, T, R> {
- fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
@@ -80,13 +80,13 @@ impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockReadGuard<'_, T, R> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<T: Debug + ?Sized, R: RawRwLock> Debug for RwLockReadGuard<'_, T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Debug::fmt(&**self, f)
}
}
impl<T: Display + ?Sized, R: RawRwLock> Display for RwLockReadGuard<'_, T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Display::fmt(&**self, f)
}
}
diff --git a/src/rwlock/rwlock.rs b/src/rwlock/rwlock.rs
index 6adf73a..72e7742 100755
--- a/src/rwlock/rwlock.rs
+++ b/src/rwlock/rwlock.rs
@@ -1,8 +1,9 @@
-use std::cell::UnsafeCell;
-use std::fmt::Debug;
-use std::marker::PhantomData;
-use std::panic::AssertUnwindSafe;
+use core::cell::UnsafeCell;
+use core::fmt::Debug;
+use core::marker::PhantomData;
+use core::panic::AssertUnwindSafe;
+use alloc::vec::Vec;
use lock_api::RawRwLock;
use crate::handle_unwind::handle_unwind;
@@ -163,7 +164,7 @@ impl<T, R: RawRwLock> RwLock<T, R> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<T: Debug, R: RawRwLock> Debug for RwLock<T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
// safety: this is just a try lock, and the value is dropped
// immediately after, so there's no risk of blocking ourselves
// or any other threads
@@ -172,7 +173,7 @@ impl<T: Debug, R: RawRwLock> Debug for RwLock<T, R> {
} else {
struct LockedPlaceholder;
impl Debug for LockedPlaceholder {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("<locked>")
}
}
@@ -586,6 +587,8 @@ impl<T: ?Sized, R: RawRwLock> RwLock<T, R> {
/// Attempts to create an exclusive lock without a key. Locking this
/// without exclusive access to the key is undefined behavior.
#[cfg(test)]
+ #[allow(clippy::allow_attributes)]
+ #[allow(dead_code)]
pub(crate) unsafe fn try_write_no_key(&self) -> Option<RwLockWriteRef<'_, T, R>> {
unsafe {
if self.raw_try_write() {
diff --git a/src/rwlock/write_guard.rs b/src/rwlock/write_guard.rs
index 823f7a4..5e367bd 100755
--- a/src/rwlock/write_guard.rs
+++ b/src/rwlock/write_guard.rs
@@ -1,7 +1,7 @@
-use std::fmt::{Debug, Display};
-use std::hash::Hash;
-use std::marker::PhantomData;
-use std::ops::{Deref, DerefMut};
+use core::fmt::{Debug, Display};
+use core::hash::Hash;
+use core::marker::PhantomData;
+use core::ops::{Deref, DerefMut};
use lock_api::RawRwLock;
@@ -16,7 +16,7 @@ use super::{RwLock, RwLockWriteGuard, RwLockWriteRef};
#[mutants::skip] // hashing involves PRNG and is difficult to test
#[cfg(not(tarpaulin_include))]
impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockWriteRef<'_, T, R> {
- fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
@@ -24,13 +24,13 @@ impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockWriteRef<'_, T, R> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<T: Debug + ?Sized, R: RawRwLock> Debug for RwLockWriteRef<'_, T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Debug::fmt(&**self, f)
}
}
impl<T: Display + ?Sized, R: RawRwLock> Display for RwLockWriteRef<'_, T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Display::fmt(&**self, f)
}
}
@@ -87,7 +87,7 @@ impl<'a, T: ?Sized + 'a, R: RawRwLock> RwLockWriteRef<'a, T, R> {
#[mutants::skip] // hashing involves PRNG and is difficult to test
#[cfg(not(tarpaulin_include))]
impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockWriteGuard<'_, T, R> {
- fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
@@ -95,13 +95,13 @@ impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockWriteGuard<'_, T, R> {
#[mutants::skip]
#[cfg(not(tarpaulin_include))]
impl<T: Debug + ?Sized, R: RawRwLock> Debug for RwLockWriteGuard<'_, T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Debug::fmt(&**self, f)
}
}
impl<T: Display + ?Sized, R: RawRwLock> Display for RwLockWriteGuard<'_, T, R> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Display::fmt(&**self, f)
}
}
diff --git a/tests/evil_mutex.rs b/tests/evil_mutex.rs
index ef6f31a..2eebb86 100755
--- a/tests/evil_mutex.rs
+++ b/tests/evil_mutex.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "std")]
+
use std::sync::Arc;
use happylock::collection::{BoxedLockCollection, RetryingLockCollection};
diff --git a/tests/evil_rwlock.rs b/tests/evil_rwlock.rs
index a57a27a..679928b 100755
--- a/tests/evil_rwlock.rs
+++ b/tests/evil_rwlock.rs
@@ -1,10 +1,11 @@
-use std::panic::AssertUnwindSafe;
-use std::sync::Arc;
+#![cfg(feature = "std")]
use happylock::collection::{BoxedLockCollection, RetryingLockCollection};
use happylock::rwlock::RwLock;
use happylock::ThreadKey;
use lock_api::{GuardNoSend, RawRwLock};
+use std::panic::AssertUnwindSafe;
+use std::sync::Arc;
struct EvilRwLock {
inner: parking_lot::RawRwLock,
diff --git a/tests/evil_try_mutex.rs b/tests/evil_try_mutex.rs
index 22834be..5978f02 100755
--- a/tests/evil_try_mutex.rs
+++ b/tests/evil_try_mutex.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "std")]
+
use std::sync::Arc;
use happylock::{
diff --git a/tests/evil_try_rwlock.rs b/tests/evil_try_rwlock.rs
index acba794..9b5db06 100755
--- a/tests/evil_try_rwlock.rs
+++ b/tests/evil_try_rwlock.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "std")]
+
use std::sync::Arc;
use happylock::collection::{BoxedLockCollection, RetryingLockCollection};
diff --git a/tests/evil_unlock_mutex.rs b/tests/evil_unlock_mutex.rs
index c21fc34..dc35d81 100755
--- a/tests/evil_unlock_mutex.rs
+++ b/tests/evil_unlock_mutex.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "std")]
+
use std::sync::Arc;
use happylock::collection::{BoxedLockCollection, RetryingLockCollection};
diff --git a/tests/evil_unlock_rwlock.rs b/tests/evil_unlock_rwlock.rs
index 577de85..550ebe3 100755
--- a/tests/evil_unlock_rwlock.rs
+++ b/tests/evil_unlock_rwlock.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "std")]
+
use std::sync::Arc;
use happylock::collection::{BoxedLockCollection, RetryingLockCollection};
diff --git a/tests/forget.rs b/tests/forget.rs
index 755bdb1..0c74c84 100755
--- a/tests/forget.rs
+++ b/tests/forget.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "std")]
+
use happylock::{Mutex, ThreadKey};
#[test]
diff --git a/tests/retry.rs b/tests/retry.rs
index 64e0918..f27bd5e 100755
--- a/tests/retry.rs
+++ b/tests/retry.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "std")]
+
use std::time::Duration;
use happylock::{collection::RetryingLockCollection, Mutex, ThreadKey};
diff --git a/tests/retry_rw.rs b/tests/retry_rw.rs
index 0a946b0..d95d001 100755
--- a/tests/retry_rw.rs
+++ b/tests/retry_rw.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "std")]
+
use std::time::Duration;
use happylock::{collection::RetryingLockCollection, RwLock, ThreadKey};