use cubecl_server::driver::DevicePoison;
use cubecl_server::server::ServerError;
use std::sync::{Arc, OnceLock};
#[derive(Clone, Debug, Default)]
pub struct PoisonWatch {
reason: Arc<OnceLock<String>>,
}
impl PoisonWatch {
pub fn watch(device: &wgpu::Device) -> Self {
let poison = Self::default();
let reason = poison.reason.clone();
device.set_device_lost_callback(move |kind, message| {
let _ = reason.set(format!("{kind:?}: {message}"));
log::error!("the wgpu device was lost ({kind:?}): {message}");
});
let reason = poison.reason.clone();
device.on_uncaptured_error(Arc::new(move |error| {
if reason.get().is_some() {
log::debug!("error on a poisoned wgpu device: {error}");
} else {
panic!("wgpu error: {error}");
}
}));
poison
}
pub fn is_poisoned(&self) -> bool {
self.reason.get().is_some()
}
pub fn check(&self) -> Result<(), ServerError> {
match self.reason.get() {
Some(reason) => Err(DevicePoison::new(reason.clone()).into()),
None => Ok(()),
}
}
}