1 | //! Package up unwind recovery. Note that if you are in some sensitive |
2 | //! place, you can use the `AbortIfPanic` helper to protect against |
3 | //! accidental panics in the rayon code itself. |
4 | |
5 | use std::any::Any; |
6 | use std::panic::{self, AssertUnwindSafe}; |
7 | use std::thread; |
8 | |
9 | /// Executes `f` and captures any panic, translating that panic into a |
10 | /// `Err` result. The assumption is that any panic will be propagated |
11 | /// later with `resume_unwinding`, and hence `f` can be treated as |
12 | /// exception safe. |
13 | pub(super) fn halt_unwinding<F, R>(func: F) -> thread::Result<R> |
14 | where |
15 | F: FnOnce() -> R, |
16 | { |
17 | panic::catch_unwind(AssertUnwindSafe(func)) |
18 | } |
19 | |
20 | pub(super) fn resume_unwinding(payload: Box<dyn Any + Send>) -> ! { |
21 | panic::resume_unwind(payload) |
22 | } |
23 | |
24 | pub(super) struct AbortIfPanic; |
25 | |
26 | impl Drop for AbortIfPanic { |
27 | fn drop(&mut self) { |
28 | eprintln!("Rayon: detected unexpected panic; aborting" ); |
29 | ::std::process::abort(); |
30 | } |
31 | } |
32 | |