use super::{current_worker, Attr, FnOnceFuture, JoinHandle, Runtime, Sleep, TaskRef, Yield};
use crate::Error;
use core::future::Future;
use core::time::Duration;
pub fn block_on_with<T>(future: T, attr: &Attr) -> Result<T::Output, Error>
where
T: Future
{
if let Ok(task) = sched(future, attr) {
JoinHandle::<T::Output>::new(task).join()
} else {
Err(Error::default())
}
}
pub fn block_on<T>(future: T) -> Result<T::Output, Error>
where
T: Future
{
block_on_with(future, &Attr::default())
}
pub fn spawn_with<T>(future: T, attr: &Attr) -> JoinHandle<T::Output>
where
T: Future + Send + 'static,
T::Output: Send + 'static,
{
if let Ok(task) = sched(future, attr) {
JoinHandle::<T::Output>::new(task)
} else {
JoinHandle::<T::Output>::null()
}
}
pub fn spawn<T>(future: T) -> JoinHandle<T::Output>
where
T: Future + Send + 'static,
T::Output: Send + 'static,
{
spawn_with(future, &Attr::default())
}
pub fn spawn_fn<F, R>(f: F) -> JoinHandle<R>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
spawn(FnOnceFuture::new(f))
}
pub fn spawn_fn_with<F, R>(f: F, attr: &Attr) -> JoinHandle<R>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
spawn_with(FnOnceFuture::new(f), attr)
}
pub fn spawn_local_with<T>(future: T, attr: &Attr) -> JoinHandle<T::Output>
where
T: Future + 'static,
T::Output: 'static,
{
if let Some(worker) = current_worker() {
if let Ok(task) = worker.spawn_local(future, attr) {
return JoinHandle::<T::Output>::new(task);
}
}
JoinHandle::<T::Output>::null()
}
pub fn spawn_local<T>(future: T) -> JoinHandle<T::Output>
where
T: Future + 'static,
T::Output: 'static,
{
spawn_local_with(future, &Attr::default())
}
pub fn spawn_fn_local_with<F, R>(f: F, attr: &Attr) -> JoinHandle<R>
where
F: FnOnce() -> R + 'static,
R: 'static,
{
spawn_local_with(FnOnceFuture::new(f), attr)
}
pub fn spawn_fn_local<F, R>(f: F) -> JoinHandle<R>
where
F: FnOnce() -> R + 'static,
R: 'static,
{
spawn_local(FnOnceFuture::new(f))
}
pub async fn sleep(timeout: Duration) {
Sleep::new(timeout).await
}
pub async fn yield_now() {
Yield::new().await
}
fn sched<T: Future>(future: T, attr: &Attr) -> Result<TaskRef, Error> {
if let Some(worker) = current_worker() {
if worker.in_group(attr.group_id) {
return worker.spawn(future, attr);
}
}
Runtime::get(attr.group_id).spawn(future, attr)
}
#[cfg(test)]
mod test {
use crate::runtime::*;
#[test]
fn test_future() {
let _ = Builder::new().nth(1).build();
async fn test_foo() -> i32 {
100
}
let val = spawn(test_foo()).join().unwrap();
assert_eq!(val, 100);
}
#[test]
fn test_sleep() {
let _ = Builder::new().nth(1).build();
async fn test_sleep(val: i32) -> i32 {
yield_now().await;
val + 100
}
let val = spawn(test_sleep(100)).join().unwrap();
assert_eq!(val, 200);
}
}