use std::{future::Future, panic::Location};
pub use crate::{
backend::tokio::task::{JoinError, JoinHandle},
flash::yield_now,
};
use crate::{
backend::tokio::{backend::task, runtime::Handle, task as native_task},
flash::system::{
credit,
credit::{DedicatedSlot, Participant},
},
maybe_send::MaybeSend,
};
#[track_caller]
pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
let on = crate::flash::ambient_snapshot();
let loc = Location::caller();
task::spawn(crate::flash::with_ambient(
on,
crate::flash::participate(crate::no_block::watch_blanket_at("spawn", loc, future), loc),
))
}
#[track_caller]
pub fn spawn_on<F>(handle: &Handle, future: F) -> JoinHandle<F::Output>
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
let on = crate::flash::ambient_snapshot();
let loc = Location::caller();
handle.spawn(crate::flash::with_ambient(
on,
crate::flash::participate(crate::no_block::watch_blanket_at("spawn", loc, future), loc),
))
}
pub fn spawn_blocking<F, R>(f: F) -> JoinHandle<R>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
let ambient = crate::flash::ambient_snapshot();
let slot = ambient.then(DedicatedSlot::reserve);
native_task::spawn_blocking(move || {
let _ambient = crate::flash::set_ambient_for_spawn(ambient);
credit::reset_credit();
if let Some(slot) = slot {
let _pacer = slot.claim_pooled();
f()
} else {
let _exit = Participant::unreserved();
f()
}
})
}
pub fn spawn_sync<F, R>(f: F) -> JoinHandle<R>
where
F: FnOnce() -> R + MaybeSend + 'static,
R: MaybeSend + 'static,
{
spawn_blocking(f)
}
pub fn spawn_blocking_on<F, R>(handle: &Handle, f: F) -> JoinHandle<R>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
let ambient = crate::flash::ambient_snapshot();
let slot = ambient.then(DedicatedSlot::reserve);
handle.spawn_blocking(move || {
let _ambient = crate::flash::set_ambient_for_spawn(ambient);
credit::reset_credit();
if let Some(slot) = slot {
let _pacer = slot.claim_pooled();
f()
} else {
let _exit = Participant::unreserved();
f()
}
})
}