unwind_context/
panic_detector.rs

1/// An utility trait which is used to detect panic.
2///
3/// # Examples
4///
5/// ```rust
6/// use core::sync::atomic::{self, AtomicBool};
7///
8/// use unwind_context::unwind_context_with_fmt;
9///
10/// #[derive(Copy, Clone, Debug)]
11/// pub struct NoStdPanicFlag<'a>(&'a AtomicBool);
12///
13/// impl unwind_context::PanicDetector for NoStdPanicFlag<'_> {
14///     fn is_panicking(&self) -> bool {
15///         self.0.load(atomic::Ordering::Relaxed)
16///     }
17/// }
18///
19/// fn func(foo: u32, bar: &str, writer: &mut String, panic_flag: NoStdPanicFlag<'_>) {
20///     let ctx =
21///         unwind_context_with_fmt!((foo, bar), writer = writer, panic_detector = panic_flag,);
22///     // ...
23/// }
24/// ```
25
26pub trait PanicDetector {
27    /// Determines whether the current thread is unwinding because of panic.
28    ///
29    /// # Panics
30    ///
31    /// Implementations should generally avoid [`panic!`]ing, because
32    /// `is_panicking()` may itself be called during unwinding due to a
33    /// panic, and if the `is_panicking()` panics in that situation (a “double
34    /// panic”), this will likely abort the program.
35    fn is_panicking(&self) -> bool;
36}
37
38/// A default [`PanicDetector`] for a crates compiled with the Rust standard
39/// library.
40///
41/// It uses `std::thread::panicking()` to detect whether the current thread is
42/// unwinding because of panic.
43///
44/// # Examples
45///
46/// ```rust
47/// use unwind_context::unwind_context_with_fmt;
48///
49/// fn func(foo: u32, bar: &str, writer: &mut String) {
50///     let ctx = unwind_context_with_fmt!(
51///         (foo, bar),
52///         writer = writer,
53///         panic_detector = unwind_context::StdPanicDetector,
54///     );
55///     // ...
56/// }
57/// ```
58#[cfg(feature = "std")]
59#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
60#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
61pub struct StdPanicDetector;
62
63#[cfg(feature = "std")]
64#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
65impl PanicDetector for StdPanicDetector {
66    #[inline]
67    fn is_panicking(&self) -> bool {
68        std::thread::panicking()
69    }
70}