#[cfg(target_has_atomic = "ptr")]
use alloc::{sync::Arc, task::Wake};
#[cfg(not(target_has_atomic = "ptr"))]
use portable_atomic_util::{task::Wake, Arc};
use alloc::{boxed::Box, vec::Vec};
use core::{
future::Future,
pin::Pin,
task::{Context, Poll, Waker},
};
pub type Reader = Pin<Box<dyn Future<Output = Vec<u8>> + Send>>;
pub fn reader_from_concrete(val: Vec<u8>) -> Reader {
Box::pin(async move { val })
}
struct DummyWaker;
impl Wake for DummyWaker {
#[cfg(target_has_atomic = "ptr")]
fn wake(self: Arc<Self>) {}
#[cfg(target_has_atomic = "ptr")]
fn wake_by_ref(self: &Arc<Self>) {}
#[cfg(not(target_has_atomic = "ptr"))]
fn wake(_this: Arc<Self>) {}
#[cfg(not(target_has_atomic = "ptr"))]
fn wake_by_ref(_this: &Arc<Self>) {}
}
pub fn read_sync<F: Future<Output = T>, T>(f: F) -> T {
try_read_sync(f).expect("Failed to read tensor data synchronously. This can happen on platforms that don't support blocking futures like WASM. If possible, try using an async variant of this function instead.")
}
pub fn try_read_sync<F: Future<Output = T>, T>(f: F) -> Option<T> {
let waker = Waker::from(Arc::new(DummyWaker));
let mut context = Context::from_waker(&waker);
let mut pinned = core::pin::pin!(f);
match pinned.as_mut().poll(&mut context) {
Poll::Ready(output) => Some(output),
#[cfg(all(not(target_family = "wasm"), feature = "std"))]
Poll::Pending => Some(pollster::block_on(pinned)),
#[cfg(any(target_family = "wasm", not(feature = "std")))]
Poll::Pending => None,
}
}