From 4ba03be97e6cc7e790bbc9bfc18caaa228c8a262 Mon Sep 17 00:00:00 2001 From: Botahamec Date: Fri, 28 Feb 2025 16:09:11 -0500 Subject: Scoped lock API --- tests/evil_try_mutex.rs | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 tests/evil_try_mutex.rs (limited to 'tests/evil_try_mutex.rs') diff --git a/tests/evil_try_mutex.rs b/tests/evil_try_mutex.rs new file mode 100644 index 0000000..5c31a91 --- /dev/null +++ b/tests/evil_try_mutex.rs @@ -0,0 +1,81 @@ +use std::sync::Arc; + +use happylock::{ + collection::{BoxedLockCollection, RetryingLockCollection}, + mutex::Mutex, + ThreadKey, +}; +use lock_api::{GuardNoSend, RawMutex}; + +struct EvilMutex { + inner: parking_lot::RawMutex, +} + +unsafe impl RawMutex for EvilMutex { + #[allow(clippy::declare_interior_mutable_const)] + const INIT: Self = Self { + inner: parking_lot::RawMutex::INIT, + }; + + type GuardMarker = GuardNoSend; + + fn lock(&self) { + self.inner.lock() + } + + fn try_lock(&self) -> bool { + panic!("mwahahahaha"); + } + + unsafe fn unlock(&self) { + self.inner.unlock() + } +} + +#[test] +fn boxed_mutexes() { + let mut key = ThreadKey::get().unwrap(); + let good_mutex: Arc> = Arc::new(Mutex::new(5)); + let evil_mutex: Arc> = Arc::new(Mutex::new(7)); + let useless_mutex: Arc> = Arc::new(Mutex::new(10)); + let c_good = Arc::clone(&good_mutex); + let c_evil = Arc::clone(&evil_mutex); + let c_useless = Arc::clone(&useless_mutex); + + let r = std::thread::spawn(move || { + let key = ThreadKey::get().unwrap(); + let collection = BoxedLockCollection::try_new((&*c_good, &*c_evil, &*c_useless)).unwrap(); + let g = collection.try_lock(key); + println!("{}", g.unwrap().1); + }) + .join(); + + assert!(r.is_err()); + assert!(good_mutex.scoped_try_lock(&mut key, |_| {}).is_ok()); + assert!(evil_mutex.scoped_try_lock(&mut key, |_| {}).is_err()); + assert!(useless_mutex.scoped_try_lock(&mut key, |_| {}).is_ok()); +} + +#[test] +fn retrying_mutexes() { + let mut key = ThreadKey::get().unwrap(); + let good_mutex: Arc> = Arc::new(Mutex::new(5)); + let evil_mutex: Arc> = Arc::new(Mutex::new(7)); + let useless_mutex: Arc> = Arc::new(Mutex::new(10)); + let c_good = Arc::clone(&good_mutex); + let c_evil = Arc::clone(&evil_mutex); + let c_useless = Arc::clone(&useless_mutex); + + let r = std::thread::spawn(move || { + let key = ThreadKey::get().unwrap(); + let collection = + RetryingLockCollection::try_new((&*c_good, &*c_evil, &*c_useless)).unwrap(); + let _ = collection.try_lock(key); + }) + .join(); + + assert!(r.is_err()); + assert!(good_mutex.scoped_try_lock(&mut key, |_| {}).is_ok()); + assert!(evil_mutex.scoped_try_lock(&mut key, |_| {}).is_err()); + assert!(useless_mutex.scoped_try_lock(&mut key, |_| {}).is_ok()); +} -- cgit v1.2.3