use core::future::Future;
use core::pin::pin;
use core::task::Poll;
use std::sync::atomic::Ordering;
use super::Inner;
impl Inner {
pub(crate) fn shut_down_on_panic(&self) {
if !self.panicked.swap(true, Ordering::AcqRel) {
self.workers.stop_all();
self.on_panic.notify_waiters();
}
}
}
pub(super) async fn watched<F: Future>(inner: &Inner, future: F) -> F::Output {
let mut notified = pin!(inner.on_panic.notified());
let mut future = pin!(future);
core::future::poll_fn(|cx| {
if inner.panicked.load(Ordering::Acquire) {
shut_down();
}
if let Poll::Ready(output) = future.as_mut().poll(cx) {
return Poll::Ready(output);
}
if notified.as_mut().poll(cx).is_ready() {
shut_down();
}
Poll::Pending
})
.await
}
#[cold]
#[expect(
clippy::panic,
reason = "`UnhandledPanic::ShutdownRuntime`: every `block_on` of the runtime panics, as documented"
)]
fn shut_down() -> ! {
panic!("the runtime shut down because one of its tasks panicked")
}