use std::time::{Duration, Instant};
const DISPATCH_TIMEOUT: Duration = Duration::from_secs(30);
pub(super) fn wait_for_readback(
device: &wgpu::Device,
receiver: std::sync::mpsc::Receiver<Result<(), wgpu::BufferAsyncError>>,
) -> Result<Result<(), wgpu::BufferAsyncError>, String> {
let deadline = Instant::now() + DISPATCH_TIMEOUT;
loop {
device.poll(wgpu::Maintain::Poll);
match receiver.try_recv() {
Ok(result) => return Ok(result),
Err(std::sync::mpsc::TryRecvError::Disconnected) => {
return Err(
"Fix: GPU readback channel closed before map_async completed. Keep the readback receiver alive until the callback fires."
.to_string(),
);
}
Err(std::sync::mpsc::TryRecvError::Empty) => {}
}
if Instant::now() >= deadline {
return Err(format!(
"Fix: GPU dispatch/readback timed out after {}s. Check for device loss, a wedged adapter, or a shader that never completes.",
DISPATCH_TIMEOUT.as_secs()
));
}
std::thread::sleep(Duration::from_millis(1));
}
}