use crate::error::Result;
use std::time::Duration;
pub trait HalFence: Send + Sync + 'static {
fn is_signaled(&self) -> Result<bool>;
fn wait(&self, timeout: Duration) -> Result<bool>;
#[cfg(unix)]
fn export_sync_file(&self) -> Result<std::os::fd::OwnedFd> {
Err(crate::Error::Unsupported("sync_file export"))
}
}
impl HalFence for std::convert::Infallible {
fn is_signaled(&self) -> Result<bool> {
match *self {}
}
fn wait(&self, _timeout: Duration) -> Result<bool> {
match *self {}
}
}
pub const FRAME_WAIT_TIMEOUT: Duration = Duration::from_secs(5);
#[cfg(test)]
mod tests {
use super::*;
use crate::Error;
use std::sync::atomic::{AtomicBool, Ordering};
struct TestFence {
signaled: AtomicBool,
}
impl HalFence for TestFence {
fn is_signaled(&self) -> Result<bool> {
Ok(self.signaled.load(Ordering::Acquire))
}
fn wait(&self, _timeout: Duration) -> Result<bool> {
self.is_signaled()
}
}
#[test]
fn fence_export_defaults_to_unsupported_rather_than_panicking() {
let fence = TestFence {
signaled: AtomicBool::new(false),
};
#[cfg(unix)]
assert!(matches!(
fence.export_sync_file(),
Err(Error::Unsupported(_))
));
assert!(!fence.is_signaled().unwrap());
}
#[test]
fn timeout_is_reported_as_a_value_not_an_error() {
let fence = TestFence {
signaled: AtomicBool::new(false),
};
assert!(!fence.wait(Duration::from_millis(0)).unwrap());
fence.signaled.store(true, Ordering::Release);
assert!(fence.wait(Duration::from_millis(0)).unwrap());
}
}