use super::*;
pub async fn yielding<R, T: FnOnce() -> R>(x: T) -> R {
let out = x();
sleep(0).await;
out
}
cfg_if! {
if #[cfg(all(target_arch = "wasm32", target_os = "unknown", feature="rt-wasm-bindgen"))] {
use async_executors::{Bindgen, LocalSpawnHandleExt, SpawnHandleExt};
pub fn spawn<Out>(_name: &str, future: impl Future<Output = Out> + Send + 'static) -> MustJoinHandle<Out>
where
Out: Send + 'static,
{
MustJoinHandle::new(
Bindgen
.spawn_handle(future)
.expect_or_log("wasm-bindgen-futures spawn_handle_local should never error out"),
)
}
pub fn spawn_local<Out>(_name: &str, future: impl Future<Output = Out> + 'static) -> MustJoinHandle<Out>
where
Out: 'static,
{
MustJoinHandle::new(
Bindgen
.spawn_handle_local(future)
.expect_or_log("wasm-bindgen-futures spawn_handle_local should never error out"),
)
}
pub fn spawn_detached<Out>(_name: &str, future: impl Future<Output = Out> + Send + 'static)
where
Out: Send + 'static,
{
Bindgen
.spawn_handle_local(future)
.expect_or_log("wasm-bindgen-futures spawn_handle_local should never error out")
.detach()
}
pub fn spawn_detached_local<Out>(_name: &str, future: impl Future<Output = Out> + 'static)
where
Out: 'static,
{
Bindgen
.spawn_handle_local(future)
.expect_or_log("wasm-bindgen-futures spawn_handle_local should never error out")
.detach()
}
pub async fn blocking_yielding<R: Send + 'static>(x: impl FnOnce() -> R + Send + 'static) -> R {
yielding(x).await
}
pub async fn cpu_yielding<R: Send + 'static>(x: impl FnOnce() -> R + Send + 'static) -> R {
yielding(x).await
}
pub async fn scaled_yielding<
N: PartialOrd,
R: Send + 'static,
T: FnOnce() -> R + Send + 'static,
>(
_n: N,
_yield_n: N,
_cpu_n: N,
x: T,
) -> R {
yielding(x).await
}
} else {
pub fn spawn<Out>(name: &str, future: impl Future<Output = Out> + Send + 'static) -> MustJoinHandle<Out>
where
Out: Send + 'static,
{
cfg_if! {
if #[cfg(feature="rt-async-std")] {
MustJoinHandle::new(async_std::task::Builder::new().name(name.to_string()).spawn(future).unwrap_or_log())
} else if #[cfg(all(tokio_unstable, feature="rt-tokio", feature="tracing"))] {
MustJoinHandle::new(tokio::task::Builder::new().name(name).spawn(future).unwrap_or_log())
} else if #[cfg(feature="rt-tokio")] {
let _name = name;
MustJoinHandle::new(tokio::task::spawn(future))
}
}
}
pub fn spawn_local<Out>(name: &str, future: impl Future<Output = Out> + 'static) -> MustJoinHandle<Out>
where
Out: 'static,
{
cfg_if! {
if #[cfg(feature="rt-async-std")] {
MustJoinHandle::new(async_std::task::Builder::new().name(name.to_string()).local(future).unwrap_or_log())
} else if #[cfg(all(tokio_unstable, feature="rt-tokio", feature="tracing"))] {
MustJoinHandle::new(tokio::task::Builder::new().name(name).spawn_local(future).unwrap_or_log())
} else if #[cfg(feature="rt-tokio")] {
let _name = name;
MustJoinHandle::new(tokio::task::spawn_local(future))
}
}
}
pub fn spawn_detached<Out>(name: &str, future: impl Future<Output = Out> + Send + 'static)
where
Out: Send + 'static,
{
cfg_if! {
if #[cfg(feature="rt-async-std")] {
drop(async_std::task::Builder::new().name(name.to_string()).spawn(future).unwrap_or_log());
} else if #[cfg(all(tokio_unstable, feature="rt-tokio", feature="tracing"))] {
drop(tokio::task::Builder::new().name(name).spawn(future).unwrap_or_log());
} else if #[cfg(feature="rt-tokio")] {
let _name = name;
drop(tokio::task::spawn(future))
}
}
}
pub fn spawn_detached_local<Out>(name: &str,future: impl Future<Output = Out> + 'static)
where
Out: 'static,
{
cfg_if! {
if #[cfg(feature="rt-async-std")] {
drop(async_std::task::Builder::new().name(name.to_string()).local(future).unwrap_or_log());
} else if #[cfg(all(tokio_unstable, feature="rt-tokio", feature="tracing"))] {
drop(tokio::task::Builder::new().name(name).spawn_local(future).unwrap_or_log());
} else if #[cfg(feature="rt-tokio")] {
let _name = name;
drop(tokio::task::spawn_local(future))
}
}
}
pub async fn blocking_wrapper<F, R>(blocking_task: F) -> R
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
cfg_if! {
if #[cfg(feature="rt-async-std")] {
async_std::task::spawn_blocking(blocking_task).await
} else if #[cfg(feature="rt-tokio")] {
tokio::task::spawn_blocking(blocking_task).await.unwrap_or_log()
} else {
#[compile_error("must use an executor")]
}
}
}
pub async fn blocking_yielding<R: Send + 'static>(x: impl FnOnce() -> R + Send + 'static) -> R
{
blocking_wrapper(x).await
}
pub async fn cpu_yielding<R: Send + 'static>(x: impl FnOnce() -> R + Send + 'static) -> R {
let (tx, rx) = flume::bounded(1);
cpu_pool_spawn_fifo(Box::new(move || {
let result = x();
let _ = tx.send(result);
}));
rx.recv_async().await.unwrap_or_log()
}
pub async fn scaled_yielding<
N: PartialOrd,
R: Send + 'static,
T: FnOnce() -> R + Send + 'static,
>(
n: N,
yield_n: N,
cpu_n: N,
x: T,
) -> R {
if n < yield_n {
x()
} else if n < cpu_n {
yielding(x).await
} else {
cpu_yielding(x).await
}
}
}
}