Files
rust/library/std/tests/sync/lib.rs
Matthias Krüger 8d6356b8d8 Rollup merge of #143191 - connortsui20:stabilize-rwlock-downgrade, r=tgross35
Stabilize `rwlock_downgrade` library feature

Tracking Issue: https://github.com/rust-lang/rust/issues/128203

Method to be stabilized:

```rust
impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
    pub fn downgrade(s: Self) -> RwLockReadGuard<'a, T> {}
}
```

~~I would like to point out that my documentation comment is longer than ideal, but at the same time I don't really know how else to show why `downgrade` is actually necessary (instead of just unlocking and relocking). If anyone has ideas for making this more concise that would be great!~~ I have made the documentation a bit more clear.

Stabilization report: https://github.com/rust-lang/rust/issues/128203#issuecomment-3016682463
2025-10-15 23:41:00 +02:00

91 lines
3.1 KiB
Rust

#![feature(lazy_get)]
#![feature(mapped_lock_guards)]
#![feature(mpmc_channel)]
#![feature(once_cell_try)]
#![feature(lock_value_accessors)]
#![feature(reentrant_lock)]
#![feature(std_internals)]
#![feature(sync_nonpoison)]
#![feature(nonpoison_condvar)]
#![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_`.
///
/// Important: most attributes (except `cfg`) will not work properly! (They are only applied to the first test.)
/// See <https://github.com/rust-lang/rust/pull/146433> for more information.
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;