#![allow(static_mut_refs)]
use crate::fs::file::File;
use crate::linux;
use crate::sync::once::OnceLock;
use core::cell::OnceCell;
use core::pin::Pin;
use core::task::Waker;
use core::{cell::RefCell, marker::PhantomData};
use crate::fs::*;
use crate::net::*;
use alloc::boxed::Box;
#[thread_local]
static mut RT: OnceCell<OptimalRuntime> = OnceCell::new();
type OptimalRuntime = linux::runtime::Runtime;
pub trait Share {
fn spawn<F, R>(&self, future: F) -> Join<R>
where
F: Future<Output = R> + Send + 'static,
R: Send + 'static;
}
pub trait Runtime<S: Share>: 'static + Sized {
type TcpStream: tcp::Stream<Self, S>;
type TcpListener: tcp::Listener<Self, S>;
type UdpSocket: udp::Socket<Self, S>;
type UdpEndpoint: udp::Endpoint<Self, S>;
type File: File<Self, S>;
type FileSystem: FileSystem<Self, S>;
fn for_platform() -> Self
where
Self: Sized;
fn share(&self) -> &S;
fn spawn_local<F, R>(&self, future: F) -> Join<R>
where
F: Future<Output = R> + 'static,
R: 'static;
fn block_on<F>(&self, future: F) -> F::Output
where
F: Future;
}
pub struct Join<Ret>(u64, PhantomData<Ret>);
pub(crate) fn rt() -> &'static OptimalRuntime {
unsafe { &*RT.get_or_init(OptimalRuntime::for_platform) }
}
pub(crate) fn spawn<R: Send + 'static>(fut: impl Future<Output = R> + Send + 'static) -> Join<R> {
rt().share().spawn(fut)
}
pub(crate) fn spawn_local<R: 'static>(fut: impl Future<Output = R> + 'static) -> Join<R> {
rt().spawn_local(fut)
}
pub(crate) fn block_on<F: Future>(f: F) -> F::Output {
rt().block_on(f)
}
pub struct LocalTask {
future: Pin<Box<dyn Future<Output = ()>>>,
waker: Waker,
}
pub struct SharedTask {
future: Pin<Box<dyn Future<Output = ()> + Send>>,
waker: Waker,
}