diff --git a/lightning/src/lib.rs b/lightning/src/lib.rs index 1f3ab47b1ae..d4289d07d2e 100644 --- a/lightning/src/lib.rs +++ b/lightning/src/lib.rs @@ -175,20 +175,7 @@ mod prelude { pub use alloc::string::ToString; } -#[cfg(all(not(feature = "_bench_unstable"), feature = "std", test))] -mod debug_sync; #[cfg(all(not(feature = "_bench_unstable"), feature = "backtrace", feature = "std", test))] extern crate backtrace; -#[cfg(feature = "std")] -mod sync { - #[cfg(all(not(feature = "_bench_unstable"), test))] - pub use crate::debug_sync::*; - #[cfg(any(feature = "_bench_unstable", not(test)))] - pub use ::std::sync::{Arc, Mutex, Condvar, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard}; - #[cfg(any(feature = "_bench_unstable", not(test)))] - pub use crate::util::fairrwlock::FairRwLock; -} - -#[cfg(not(feature = "std"))] mod sync; diff --git a/lightning/src/debug_sync.rs b/lightning/src/sync/debug_sync.rs similarity index 85% rename from lightning/src/debug_sync.rs rename to lightning/src/sync/debug_sync.rs index b61d1cb55e8..9f7caa2c180 100644 --- a/lightning/src/debug_sync.rs +++ b/lightning/src/sync/debug_sync.rs @@ -77,7 +77,7 @@ fn get_construction_location(backtrace: &Backtrace) -> String { // Find the first frame that is after `debug_sync` (or that is in our tests) and use // that as the mutex construction site. Note that the first few frames may be in // the `backtrace` crate, so we have to ignore those. - let sync_mutex_constr_regex = regex::Regex::new(r"lightning.*debug_sync.*new").unwrap(); + let sync_mutex_constr_regex = regex::Regex::new(r"lightning.*debug_sync").unwrap(); let mut found_debug_sync = false; for frame in backtrace.frames() { for symbol in frame.symbols() { @@ -333,100 +333,3 @@ impl RwLock { } pub type FairRwLock = RwLock; - -mod tests { - use super::{RwLock, Mutex}; - - #[test] - #[should_panic] - #[cfg(not(feature = "backtrace"))] - fn recursive_lock_fail() { - let mutex = Mutex::new(()); - let _a = mutex.lock().unwrap(); - let _b = mutex.lock().unwrap(); - } - - #[test] - fn recursive_read() { - let lock = RwLock::new(()); - let _a = lock.read().unwrap(); - let _b = lock.read().unwrap(); - } - - #[test] - #[should_panic] - fn lockorder_fail() { - let a = Mutex::new(()); - let b = Mutex::new(()); - { - let _a = a.lock().unwrap(); - let _b = b.lock().unwrap(); - } - { - let _b = b.lock().unwrap(); - let _a = a.lock().unwrap(); - } - } - - #[test] - #[should_panic] - fn write_lockorder_fail() { - let a = RwLock::new(()); - let b = RwLock::new(()); - { - let _a = a.write().unwrap(); - let _b = b.write().unwrap(); - } - { - let _b = b.write().unwrap(); - let _a = a.write().unwrap(); - } - } - - #[test] - #[should_panic] - fn read_lockorder_fail() { - let a = RwLock::new(()); - let b = RwLock::new(()); - { - let _a = a.read().unwrap(); - let _b = b.read().unwrap(); - } - { - let _b = b.read().unwrap(); - let _a = a.read().unwrap(); - } - } - - #[test] - fn read_recursive_no_lockorder() { - // Like the above, but note that no lockorder is implied when we recursively read-lock a - // RwLock, causing this to pass just fine. - let a = RwLock::new(()); - let b = RwLock::new(()); - let _outer = a.read().unwrap(); - { - let _a = a.read().unwrap(); - let _b = b.read().unwrap(); - } - { - let _b = b.read().unwrap(); - let _a = a.read().unwrap(); - } - } - - #[test] - #[should_panic] - fn read_write_lockorder_fail() { - let a = RwLock::new(()); - let b = RwLock::new(()); - { - let _a = a.write().unwrap(); - let _b = b.read().unwrap(); - } - { - let _b = b.read().unwrap(); - let _a = a.write().unwrap(); - } - } -} diff --git a/lightning/src/sync/mod.rs b/lightning/src/sync/mod.rs new file mode 100644 index 00000000000..f7226a5fa34 --- /dev/null +++ b/lightning/src/sync/mod.rs @@ -0,0 +1,17 @@ +#[cfg(all(feature = "std", not(feature = "_bench_unstable"), test))] +mod debug_sync; +#[cfg(all(feature = "std", not(feature = "_bench_unstable"), test))] +pub use debug_sync::*; +#[cfg(all(feature = "std", not(feature = "_bench_unstable"), test))] +// Note that to make debug_sync's regex work this must not contain `debug_string` in the module name +mod test_lockorder_checks; + +#[cfg(all(feature = "std", any(feature = "_bench_unstable", not(test))))] +pub use ::std::sync::{Arc, Mutex, Condvar, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard}; +#[cfg(all(feature = "std", any(feature = "_bench_unstable", not(test))))] +pub use crate::util::fairrwlock::FairRwLock; + +#[cfg(not(feature = "std"))] +mod nostd_sync; +#[cfg(not(feature = "std"))] +pub use nostd_sync::*; diff --git a/lightning/src/sync.rs b/lightning/src/sync/nostd_sync.rs similarity index 100% rename from lightning/src/sync.rs rename to lightning/src/sync/nostd_sync.rs diff --git a/lightning/src/sync/test_lockorder_checks.rs b/lightning/src/sync/test_lockorder_checks.rs new file mode 100644 index 00000000000..f9f30e2cfa2 --- /dev/null +++ b/lightning/src/sync/test_lockorder_checks.rs @@ -0,0 +1,94 @@ +use crate::sync::debug_sync::{RwLock, Mutex}; + +#[test] +#[should_panic] +#[cfg(not(feature = "backtrace"))] +fn recursive_lock_fail() { + let mutex = Mutex::new(()); + let _a = mutex.lock().unwrap(); + let _b = mutex.lock().unwrap(); +} + +#[test] +fn recursive_read() { + let lock = RwLock::new(()); + let _a = lock.read().unwrap(); + let _b = lock.read().unwrap(); +} + +#[test] +#[should_panic] +fn lockorder_fail() { + let a = Mutex::new(()); + let b = Mutex::new(()); + { + let _a = a.lock().unwrap(); + let _b = b.lock().unwrap(); + } + { + let _b = b.lock().unwrap(); + let _a = a.lock().unwrap(); + } +} + +#[test] +#[should_panic] +fn write_lockorder_fail() { + let a = RwLock::new(()); + let b = RwLock::new(()); + { + let _a = a.write().unwrap(); + let _b = b.write().unwrap(); + } + { + let _b = b.write().unwrap(); + let _a = a.write().unwrap(); + } +} + +#[test] +#[should_panic] +fn read_lockorder_fail() { + let a = RwLock::new(()); + let b = RwLock::new(()); + { + let _a = a.read().unwrap(); + let _b = b.read().unwrap(); + } + { + let _b = b.read().unwrap(); + let _a = a.read().unwrap(); + } +} + +#[test] +fn read_recursive_no_lockorder() { + // Like the above, but note that no lockorder is implied when we recursively read-lock a + // RwLock, causing this to pass just fine. + let a = RwLock::new(()); + let b = RwLock::new(()); + let _outer = a.read().unwrap(); + { + let _a = a.read().unwrap(); + let _b = b.read().unwrap(); + } + { + let _b = b.read().unwrap(); + let _a = a.read().unwrap(); + } +} + +#[test] +#[should_panic] +fn read_write_lockorder_fail() { + let a = RwLock::new(()); + let b = RwLock::new(()); + { + let _a = a.write().unwrap(); + let _b = b.read().unwrap(); + } + { + let _b = b.read().unwrap(); + let _a = a.write().unwrap(); + } +}