| 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 | |