#[cfg(not(target_family = "wasm"))]
mod _impl {
use crate::compute::device_poison::PoisonWatch;
use std::thread::JoinHandle;
#[derive(Debug)]
pub struct WgpuPoll {
active_handle: std::sync::Arc<()>,
cancel_sender: std::sync::mpsc::Sender<()>,
poll_thread: JoinHandle<()>,
}
impl WgpuPoll {
pub fn new(device: wgpu::Device, queue: wgpu::Queue, poison: PoisonWatch) -> Self {
let active_handle = std::sync::Arc::new(());
let thread_check = active_handle.clone();
let (cancel_sender, cancel_receiver) = std::sync::mpsc::channel();
let poll_thread = std::thread::spawn(move || {
loop {
if std::sync::Arc::strong_count(&thread_check) > 2 && !poison.is_poisoned() {
if let Err(e) = poison.wait_unless_lost(&device, &queue, None)
&& !poison.is_poisoned()
{
log::warn!("wgpu: waiting on the device failed during sync. ({e})")
}
} else {
if cancel_receiver.try_recv().is_ok() {
break;
}
std::thread::park();
}
std::thread::yield_now();
}
});
Self {
active_handle,
cancel_sender,
poll_thread,
}
}
pub fn start_polling(&self) -> std::sync::Arc<()> {
let handle = self.active_handle.clone();
self.poll_thread.thread().unpark();
handle
}
}
impl Drop for WgpuPoll {
fn drop(&mut self) {
self.cancel_sender
.send(())
.expect("Failed to shutdown polling thread.");
self.poll_thread.thread().unpark();
}
}
}
#[cfg(target_family = "wasm")]
mod _impl {
use crate::compute::device_poison::PoisonWatch;
#[derive(Debug)]
pub struct WgpuPoll {}
impl WgpuPoll {
pub fn new(_device: wgpu::Device, _queue: wgpu::Queue, _poison: PoisonWatch) -> Self {
Self {}
}
pub fn start_polling(&self) -> alloc::sync::Arc<()> {
alloc::sync::Arc::new(())
}
}
}
pub(crate) use _impl::*;