1 | //! Task abstraction for building executors. |
2 | //! |
3 | //! To spawn a future onto an executor, we first need to allocate it on the heap and keep some |
4 | //! state attached to it. The state indicates whether the future is ready for polling, waiting to |
5 | //! be woken up, or completed. Such a stateful future is called a *task*. |
6 | //! |
7 | //! All executors have a queue that holds scheduled tasks: |
8 | //! |
9 | //! ``` |
10 | //! let (sender, receiver) = flume::unbounded(); |
11 | //! # |
12 | //! # // A future that will get spawned. |
13 | //! # let future = async { 1 + 2 }; |
14 | //! # |
15 | //! # // A function that schedules the task when it gets woken up. |
16 | //! # let schedule = move |runnable| sender.send(runnable).unwrap(); |
17 | //! # |
18 | //! # // Create a task. |
19 | //! # let (runnable, task) = async_task::spawn(future, schedule); |
20 | //! ``` |
21 | //! |
22 | //! A task is created using either [`spawn()`], [`spawn_local()`], or [`spawn_unchecked()`] which |
23 | //! return a [`Runnable`] and a [`Task`]: |
24 | //! |
25 | //! ``` |
26 | //! # let (sender, receiver) = flume::unbounded(); |
27 | //! # |
28 | //! // A future that will be spawned. |
29 | //! let future = async { 1 + 2 }; |
30 | //! |
31 | //! // A function that schedules the task when it gets woken up. |
32 | //! let schedule = move |runnable| sender.send(runnable).unwrap(); |
33 | //! |
34 | //! // Construct a task. |
35 | //! let (runnable, task) = async_task::spawn(future, schedule); |
36 | //! |
37 | //! // Push the task into the queue by invoking its schedule function. |
38 | //! runnable.schedule(); |
39 | //! ``` |
40 | //! |
41 | //! The [`Runnable`] is used to poll the task's future, and the [`Task`] is used to await its |
42 | //! output. |
43 | //! |
44 | //! Finally, we need a loop that takes scheduled tasks from the queue and runs them: |
45 | //! |
46 | //! ```no_run |
47 | //! # let (sender, receiver) = flume::unbounded(); |
48 | //! # |
49 | //! # // A future that will get spawned. |
50 | //! # let future = async { 1 + 2 }; |
51 | //! # |
52 | //! # // A function that schedules the task when it gets woken up. |
53 | //! # let schedule = move |runnable| sender.send(runnable).unwrap(); |
54 | //! # |
55 | //! # // Create a task. |
56 | //! # let (runnable, task) = async_task::spawn(future, schedule); |
57 | //! # |
58 | //! # // Push the task into the queue by invoking its schedule function. |
59 | //! # runnable.schedule(); |
60 | //! # |
61 | //! for runnable in receiver { |
62 | //! runnable.run(); |
63 | //! } |
64 | //! ``` |
65 | //! |
66 | //! Method [`run()`][`Runnable::run()`] polls the task's future once. Then, the [`Runnable`] |
67 | //! vanishes and only reappears when its [`Waker`][`core::task::Waker`] wakes the task, thus |
68 | //! scheduling it to be run again. |
69 | |
70 | #![cfg_attr (not(feature = "std" ), no_std)] |
71 | #![warn (missing_docs, missing_debug_implementations, rust_2018_idioms)] |
72 | #![doc (test(attr(deny(rust_2018_idioms, warnings))))] |
73 | #![doc (test(attr(allow(unused_extern_crates, unused_variables))))] |
74 | #![doc ( |
75 | html_favicon_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png" |
76 | )] |
77 | #![doc ( |
78 | html_logo_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png" |
79 | )] |
80 | |
81 | extern crate alloc; |
82 | |
83 | /// We can't use `?` in const contexts yet, so this macro acts |
84 | /// as a workaround. |
85 | macro_rules! leap { |
86 | ($x: expr) => {{ |
87 | match ($x) { |
88 | Some(val) => val, |
89 | None => return None, |
90 | } |
91 | }}; |
92 | } |
93 | |
94 | macro_rules! leap_unwrap { |
95 | ($x: expr) => {{ |
96 | match ($x) { |
97 | Some(val) => val, |
98 | None => panic!("called `Option::unwrap()` on a `None` value" ), |
99 | } |
100 | }}; |
101 | } |
102 | |
103 | mod header; |
104 | mod raw; |
105 | mod runnable; |
106 | mod state; |
107 | mod task; |
108 | mod utils; |
109 | |
110 | pub use crate::runnable::{ |
111 | spawn, spawn_unchecked, Builder, Runnable, Schedule, ScheduleInfo, WithInfo, |
112 | }; |
113 | pub use crate::task::{FallibleTask, Task}; |
114 | |
115 | #[cfg (feature = "std" )] |
116 | pub use crate::runnable::spawn_local; |
117 | |