use crate::error::{AtriError, AtriResult};
use crate::runtime::manager::PluginRuntime;
use atri_ffi::error::FFIResult;
use atri_ffi::future::FFIFuture;
use atri_ffi::Managed;
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, Ordering};
use std::task::{Context, Poll};
mod manager;
pub struct JoinHandle<T> {
handle: FFIFuture<FFIResult<Managed>>,
_mark: PhantomData<T>,
}
impl<T> JoinHandle<T> {
pub fn from(f: FFIFuture<FFIResult<Managed>>) -> Self {
Self {
handle: f,
_mark: PhantomData,
}
}
}
impl<T> Unpin for JoinHandle<T> {}
unsafe impl<T: Send> Send for JoinHandle<T> {}
unsafe impl<T: Send> Sync for JoinHandle<T> {}
impl<T> Future for JoinHandle<T> {
type Output = AtriResult<T>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let pin = unsafe { Pin::new_unchecked(&mut self.handle) };
match pin.poll(cx) {
Poll::Ready(ffi) => {
let result = match Result::from(ffi) {
Ok(val) => Ok(unsafe { val.into_value() }),
Err(s) => Err(AtriError::JoinError(s)),
};
Poll::Ready(result)
}
Poll::Pending => Poll::Pending,
}
}
}
pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
where
F: Future,
F: Send + 'static,
F::Output: Send + 'static,
{
PluginRuntime::spawn(future)
}
pub fn block_on<F>(future: F) -> F::Output
where
F: Future,
{
PluginRuntime::block_on(future)
}
static PANICKED: AtomicBool = AtomicBool::new(false);
pub fn after_panic() {
PANICKED.store(true, Ordering::SeqCst);
}
pub fn is_panicked() -> bool {
PANICKED.load(Ordering::Relaxed)
}