blob: f874c2ba389516774c413a85d983b1cc4e3282eb [file] [log] [blame]
#![feature(lazy_get)]
#![feature(mapped_lock_guards)]
#![feature(mpmc_channel)]
#![feature(once_cell_try)]
#![feature(lock_value_accessors)]
#![feature(reentrant_lock)]
#![feature(rwlock_downgrade)]
#![feature(std_internals)]
#![feature(sync_nonpoison)]
#![feature(nonpoison_mutex)]
#![feature(nonpoison_rwlock)]
#![allow(internal_features)]
#![feature(macro_metavar_expr_concat)] // For concatenating identifiers in macros.
mod barrier;
mod condvar;
mod lazy_lock;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod mpmc;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod mpsc;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod mpsc_sync;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod mutex;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod once;
mod once_lock;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod reentrant_lock;
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
mod rwlock;
#[path = "../common/mod.rs"]
mod common;
#[track_caller]
fn result_unwrap<T, E: std::fmt::Debug>(x: Result<T, E>) -> T {
x.unwrap()
}
/// A macro that generates two test cases for both the poison and nonpoison locks.
///
/// To write a test that tests both `poison` and `nonpoison` locks, import any of the types
/// under both `poison` and `nonpoison` using the module name `locks` instead. For example, write
/// `use locks::Mutex;` instead of `use std::sync::poiosn::Mutex`. This will import the correct type
/// for each test variant.
///
/// Write a test as normal in the `test_body`, but instead of calling `unwrap` on `poison` methods
/// that return a `LockResult` or similar, call the function `maybe_unwrap(...)` on the result.
///
/// For example, call `maybe_unwrap(mutex.lock())` instead of `mutex.lock().unwrap()` or
/// `maybe_unwrap(rwlock.read())` instead of `rwlock.read().unwrap()`.
///
/// For the `poison` types, `maybe_unwrap` will simply unwrap the `Result` (usually this is a form
/// of `LockResult`, but it could also be other kinds of results). For the `nonpoison` types, it is
/// a no-op (the identity function).
///
/// The test names will be prefiex with `poison_` or `nonpoison_`.
macro_rules! nonpoison_and_poison_unwrap_test {
(
name: $name:ident,
test_body: {$($test_body:tt)*}
) => {
// Creates the nonpoison test.
#[test]
fn ${concat(nonpoison_, $name)}() {
#[allow(unused_imports)]
use ::std::convert::identity as maybe_unwrap;
use ::std::sync::nonpoison as locks;
$($test_body)*
}
// Creates the poison test with the suffix `_unwrap_poisoned`.
#[test]
fn ${concat(poison_, $name)}() {
#[allow(unused_imports)]
use super::result_unwrap as maybe_unwrap;
use ::std::sync::poison as locks;
$($test_body)*
}
}
}
use nonpoison_and_poison_unwrap_test;