1pub mod join;
10pub mod try_join;
11
12mod cancel;
13
14pub use self::cancel::{CancelSignal, Canceled, Canceler};
15pub use self::join::Join;
16pub use self::try_join::TryJoin;
17
18use crate::prelude::*;
19
20pub async fn sleep(duration: Duration) {
22 if duration.is_infinite() {
23 future::forever().await
24 } else {
25 async_io::Timer::after(duration.into()).await;
26 }
27}
28
29pub fn start<T>(task: impl Start<T>) -> Task<T>
31where
32 T: Send + 'static,
33{
34 task.start()
35}
36
37fn start_impl<T>(future: impl Future<Output = T> + Send + 'static) -> Task<T>
39where
40 T: Send + 'static,
41{
42 let task = async_global_executor::spawn(async move {
43 future::catch_unwind(panic::AssertUnwindSafe(future)).await.map_err(|value| Panic { value })
44 });
45
46 Task { task }
47}
48
49pub async fn yield_now() {
51 futures_lite::future::yield_now().await;
52}
53
54#[must_use = "Tasks are killed when dropped."]
56pub struct Task<T> {
57 task: async_executor::Task<Result<T, Panic>>,
58}
59
60impl<T> Task<T> {
61 pub async fn kill(self) {
63 self.task.cancel().await;
64 }
65
66 pub async fn join(self) -> Result<T, Panic> {
68 self.task.await
69 }
70}
71
72impl<T, E> Task<Result<T, E>>
73where
74 E: From<Panic>,
75{
76 pub async fn try_join(self) -> Result<T, E> {
78 self.task.await?
79 }
80}
81
82pub trait Start<T> {
84 fn start(self) -> Task<T>;
86}
87
88impl<T> Start<T> for Task<T> {
89 fn start(self) -> Task<T> {
90 self
91 }
92}
93
94impl<T, F> Start<T> for F
95where
96 T: Send + 'static,
97 F: Future<Output = T> + Send + 'static,
98{
99 fn start(self) -> Task<T> {
100 start_impl(self)
101 }
102}