1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! Taking a lock over state a panic cannot leave half-written.
//!
//! `Mutex::lock` reports that some **other thread** panicked while holding the
//! lock. That is a fact about a thread, not about the data — the standard
//! library cannot know whether the panicking thread broke an invariant, so it
//! reports the possibility and lets the caller decide.
//!
//! Most of this crate's locks guard a membership set or a derived cache, where a
//! panicking thread either inserted an entry or did not. Propagating the poison
//! there converts one thread's panic into a **permanent** fault in every later
//! reader, for the life of the process.
//!
//! One case makes that concrete. [`InFlight`] deregisters a run from a `Drop`, so
//! a panicking task deregisters too — and a poisoned lock turns that unwrap into
//! a panic inside a `Drop` during unwinding, which is an immediate `abort`.
//!
//! So the rule is per lock:
//!
//! - **Derived or membership state** — [`recover`]. Nothing to break.
//! - **An invariant across fields**, the ledger being the one here, keeps the
//! propagating unwrap: a ceiling whose accounting may have been interrupted
//! must not read as sound.
//!
//! [`InFlight`]: crate::runtime::drain
use ;
/// Lock, ignoring a poison flag left by another thread's panic.
///
/// For state where a panic cannot leave a broken invariant — see the module
/// documentation for which locks those are, and for the one that is not.
pub