background-jobs/jobs-core/src/catch_unwind.rs

39 lines
892 B
Rust
Raw Permalink Normal View History

2021-09-16 22:50:32 +00:00
use std::{
future::Future,
2022-12-09 23:38:22 +00:00
panic::AssertUnwindSafe,
2021-09-16 22:50:32 +00:00
pin::Pin,
task::{Context, Poll},
};
pub(crate) struct CatchUnwindFuture<F> {
2022-12-09 23:38:22 +00:00
future: F,
2021-09-16 22:50:32 +00:00
}
pub(crate) fn catch_unwind<F>(future: F) -> CatchUnwindFuture<F>
where
F: Future + Unpin,
{
2022-12-09 23:38:22 +00:00
CatchUnwindFuture { future }
2021-09-16 22:50:32 +00:00
}
impl<F> Future for CatchUnwindFuture<F>
where
F: Future + Unpin,
{
type Output = std::thread::Result<F::Output>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
2022-12-09 23:38:22 +00:00
let future = &mut self.get_mut().future;
2021-09-16 22:50:32 +00:00
let waker = cx.waker().clone();
2022-12-09 23:38:22 +00:00
let res = std::panic::catch_unwind(AssertUnwindSafe(|| {
2021-09-16 22:50:32 +00:00
let mut context = Context::from_waker(&waker);
2022-12-09 23:38:22 +00:00
Pin::new(future).poll(&mut context)
}));
2021-09-16 22:50:32 +00:00
match res {
Ok(poll) => poll.map(Ok),
Err(e) => Poll::Ready(Err(e)),
}
}
}