use super::task::{self, AbortHandle, AwaitHandle};
use super::{Attr, FnOnceFuture, TaskRef};
use crate::Result;
use core::future::Future;
use core::pin::Pin;
use core::task::{Context, Poll};
pub struct JoinHandle<T>(AwaitHandle<T>);
impl<T> JoinHandle<T> {
pub fn join(self) -> <AwaitHandle<T> as Future>::Output {
self.0.join()
}
pub fn abort(&self) -> bool {
self.0.abort()
}
pub fn is_finished(&self) -> bool {
self.0.is_finished()
}
pub fn abort_handle(self) -> AbortHandle<T> {
self.0.abort_handle()
}
}
impl<T> JoinHandle<T> {
pub(crate) fn new(task: TaskRef) -> Self {
Self(AwaitHandle::new(task))
}
pub(crate) fn null() -> Self {
Self(AwaitHandle::null())
}
pub(crate) fn handle(self) -> AwaitHandle<T> {
self.0
}
}
impl<T> Future for JoinHandle<T> {
type Output = Result<T>;
fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
let pinned = unsafe { Pin::new_unchecked(&mut self.0) };
Future::poll(pinned, ctx)
}
}
#[repr(C)]
pub struct JoinSet<T>(task::JoinSet<T>);
impl<T> Default for JoinSet<T> {
fn default() -> Self {
Self(task::JoinSet::default())
}
}
impl<T> JoinSet<T> {
pub const fn new() -> Self {
Self(task::JoinSet::new())
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn spawn<F>(&mut self, future: F) -> Result<()>
where
F: Future<Output = T> + Send + 'static,
T: Send + 'static,
{
self.spawn_with(future, &Attr::default())
}
pub fn spawn_with<F>(&mut self, future: F, attr: &Attr) -> Result<()>
where
F: Future<Output = T> + Send + 'static,
T: Send + 'static,
{
let attr = task::JoinSet::<T>::join_attr(attr);
let handle = super::spawn_with(future, &attr);
self.0.push_handle(handle.handle())
}
pub fn spawn_local<F>(&mut self, future: F) -> Result<()>
where
F: Future<Output = T> + 'static,
T: 'static,
{
self.spawn_local_with(future, &Attr::default())
}
pub fn spawn_local_with<F>(&mut self, future: F, attr: &Attr) -> Result<()>
where
F: Future<Output = T> + 'static,
T: 'static,
{
let attr = task::JoinSet::<T>::join_attr(attr);
let handle = super::spawn_local_with(future, &attr);
self.0.push_handle(handle.handle())
}
pub fn spawn_fn<F>(&mut self, f: F) -> Result<()>
where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
{
self.spawn(FnOnceFuture::new(f))
}
pub fn spawn_fn_with<F>(&mut self, f: F, attr: &Attr) -> Result<()>
where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
{
self.spawn_with(FnOnceFuture::new(f), attr)
}
pub fn spawn_fn_local<F>(&mut self, f: F) -> Result<()>
where
F: FnOnce() -> T + 'static,
T: 'static,
{
self.spawn_local(FnOnceFuture::new(f))
}
pub fn spawn_fn_local_with<F>(&mut self, f: F, attr: &Attr) -> Result<()>
where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
{
self.spawn_local_with(FnOnceFuture::new(f), attr)
}
pub fn abort(&mut self) {
self.0.abort();
}
pub async fn wait_all(&mut self) -> impl Iterator<Item = (usize, Result<T>)> + '_ {
self.0.wait_all().await
}
pub async fn wait_any(&mut self) -> Option<(usize, Result<T>)> {
self.0.wait_any().await
}
}