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
5use std::any::Any;
6use std::panic::{self, AssertUnwindSafe};
7use 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.
13pub(super) fn halt_unwinding<F, R>(func: F) -> thread::Result<R>
14where
15 F: FnOnce() -> R,
16{
17 panic::catch_unwind(AssertUnwindSafe(func))
18}
19
20pub(super) fn resume_unwinding(payload: Box<dyn Any + Send>) -> ! {
21 panic::resume_unwind(payload)
22}
23
24pub(super) struct AbortIfPanic;
25
26impl Drop for AbortIfPanic {
27 fn drop(&mut self) {
28 eprintln!("Rayon: detected unexpected panic; aborting");
29 ::std::process::abort();
30 }
31}
32