use std::panic::{self, AssertUnwindSafe};
use std::sync::{Arc, Mutex, mpsc};
use crate::executor::metrics::ExecutorMetricsInner;
use crate::executor::panic_handler::PanicHandler;
use crate::executor::task::BoxTask;
pub(crate) enum Message {
Run(BoxTask),
Stop,
}
pub(crate) fn run(
receiver: Arc<Mutex<mpsc::Receiver<Message>>>,
metrics: Arc<ExecutorMetricsInner>,
panic_handler: Arc<dyn PanicHandler>,
) {
loop {
let message = match receiver.lock() {
Ok(receiver) => receiver.recv(),
Err(_) => return,
};
match message {
Ok(Message::Run(task)) => {
let result = panic::catch_unwind(AssertUnwindSafe(|| {
task.run();
}));
if let Err(payload) = result {
panic_handler.handle_panic(payload.as_ref());
metrics.panicked();
}
metrics.completed();
}
Ok(Message::Stop) | Err(_) => return,
}
}
}