@@ -35,8 +35,20 @@ use crate::sys::sync as sys;
3535///
3636/// In addition, the panic detection is not ideal, so even unpoisoned mutexes
3737/// need to be handled with care, since certain panics may have been skipped.
38- /// Therefore, `unsafe` code cannot rely on poisoning for soundness. Here's an
39- /// example of **incorrect** use of poisoning:
38+ /// Here is a non-exhaustive list of situations where this might occur:
39+ ///
40+ /// - If a mutex is locked while a panic is underway, e.g. within a [`Drop`]
41+ /// implementation or a [panic hook], panicking for the second time while the
42+ /// lock is held will leave the mutex unpoisoned. Note that while double panic
43+ /// usually aborts the program, [`catch_unwind`] can prevent this.
44+ ///
45+ /// - Locking and unlocking the mutex across different panic contexts, e.g. by
46+ /// storing the guard to a [`Cell`] within [`Drop::drop`] and accessing it
47+ /// outside, or vice versa, can affect poisoning status in an unexpected way.
48+ ///
49+ /// While this rarely happens in realistic code, `unsafe` code cannot rely on
50+ /// poisoning for soundness, since the behavior of poisoning can depend on
51+ /// outside context. Here's an example of **incorrect** use of poisoning:
4052///
4153/// ```rust
4254/// use std::sync::Mutex;
@@ -58,8 +70,8 @@ use crate::sys::sync as sys;
5870/// // panics, `*ptr` keeps pointing at a dropped value. The intention
5971/// // is that this will poison the mutex, so the following calls to
6072/// // `replace_with` will panic without reading `*ptr`. But since
61- /// // poisoning is not guaranteed to occur, this can lead to
62- /// // use-after-free.
73+ /// // poisoning is not guaranteed to occur if this is run from a panic
74+ /// // hook, this can lead to use-after-free.
6375/// unsafe {
6476/// (*ptr).write(f((*ptr).read()));
6577/// }
@@ -73,6 +85,9 @@ use crate::sys::sync as sys;
7385/// [`unwrap()`]: Result::unwrap
7486/// [`PoisonError`]: super::PoisonError
7587/// [`into_inner`]: super::PoisonError::into_inner
88+ /// [panic hook]: crate::panic::set_hook
89+ /// [`catch_unwind`]: crate::panic::catch_unwind
90+ /// [`Cell`]: crate::cell::Cell
7691///
7792/// # Examples
7893///
0 commit comments