/rust/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.31/src/task/spawn.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use futures_task::{LocalSpawn, Spawn}; |
2 | | |
3 | | #[cfg(feature = "compat")] |
4 | | use crate::compat::Compat; |
5 | | |
6 | | #[cfg(feature = "channel")] |
7 | | #[cfg(feature = "std")] |
8 | | use crate::future::{FutureExt, RemoteHandle}; |
9 | | #[cfg(feature = "alloc")] |
10 | | use alloc::boxed::Box; |
11 | | #[cfg(feature = "alloc")] |
12 | | use futures_core::future::Future; |
13 | | #[cfg(feature = "alloc")] |
14 | | use futures_task::{FutureObj, LocalFutureObj, SpawnError}; |
15 | | |
16 | | impl<Sp: ?Sized> SpawnExt for Sp where Sp: Spawn {} |
17 | | impl<Sp: ?Sized> LocalSpawnExt for Sp where Sp: LocalSpawn {} |
18 | | |
19 | | /// Extension trait for `Spawn`. |
20 | | pub trait SpawnExt: Spawn { |
21 | | /// Spawns a task that polls the given future with output `()` to |
22 | | /// completion. |
23 | | /// |
24 | | /// This method returns a [`Result`] that contains a [`SpawnError`] if |
25 | | /// spawning fails. |
26 | | /// |
27 | | /// You can use [`spawn_with_handle`](SpawnExt::spawn_with_handle) if |
28 | | /// you want to spawn a future with output other than `()` or if you want |
29 | | /// to be able to await its completion. |
30 | | /// |
31 | | /// Note this method will eventually be replaced with the upcoming |
32 | | /// `Spawn::spawn` method which will take a `dyn Future` as input. |
33 | | /// Technical limitations prevent `Spawn::spawn` from being implemented |
34 | | /// today. Feel free to use this method in the meantime. |
35 | | /// |
36 | | /// ``` |
37 | | /// # { |
38 | | /// use futures::executor::ThreadPool; |
39 | | /// use futures::task::SpawnExt; |
40 | | /// |
41 | | /// let executor = ThreadPool::new().unwrap(); |
42 | | /// |
43 | | /// let future = async { /* ... */ }; |
44 | | /// executor.spawn(future).unwrap(); |
45 | | /// # } |
46 | | /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 |
47 | | /// ``` |
48 | | #[cfg(feature = "alloc")] |
49 | 0 | fn spawn<Fut>(&self, future: Fut) -> Result<(), SpawnError> |
50 | 0 | where |
51 | 0 | Fut: Future<Output = ()> + Send + 'static, |
52 | 0 | { |
53 | 0 | self.spawn_obj(FutureObj::new(Box::new(future))) |
54 | 0 | } |
55 | | |
56 | | /// Spawns a task that polls the given future to completion and returns a |
57 | | /// future that resolves to the spawned future's output. |
58 | | /// |
59 | | /// This method returns a [`Result`] that contains a [`RemoteHandle`](crate::future::RemoteHandle), or, if |
60 | | /// spawning fails, a [`SpawnError`]. [`RemoteHandle`](crate::future::RemoteHandle) is a future that |
61 | | /// resolves to the output of the spawned future. |
62 | | /// |
63 | | /// ``` |
64 | | /// # { |
65 | | /// use futures::executor::{block_on, ThreadPool}; |
66 | | /// use futures::future; |
67 | | /// use futures::task::SpawnExt; |
68 | | /// |
69 | | /// let executor = ThreadPool::new().unwrap(); |
70 | | /// |
71 | | /// let future = future::ready(1); |
72 | | /// let join_handle_fut = executor.spawn_with_handle(future).unwrap(); |
73 | | /// assert_eq!(block_on(join_handle_fut), 1); |
74 | | /// # } |
75 | | /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 |
76 | | /// ``` |
77 | | #[cfg(feature = "channel")] |
78 | | #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] |
79 | | #[cfg(feature = "std")] |
80 | 0 | fn spawn_with_handle<Fut>(&self, future: Fut) -> Result<RemoteHandle<Fut::Output>, SpawnError> |
81 | 0 | where |
82 | 0 | Fut: Future + Send + 'static, |
83 | 0 | Fut::Output: Send, |
84 | 0 | { |
85 | 0 | let (future, handle) = future.remote_handle(); |
86 | 0 | self.spawn(future)?; |
87 | 0 | Ok(handle) |
88 | 0 | } |
89 | | |
90 | | /// Wraps a [`Spawn`] and makes it usable as a futures 0.1 `Executor`. |
91 | | /// Requires the `compat` feature to enable. |
92 | | #[cfg(feature = "compat")] |
93 | | #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] |
94 | | fn compat(self) -> Compat<Self> |
95 | | where |
96 | | Self: Sized, |
97 | | { |
98 | | Compat::new(self) |
99 | | } |
100 | | } |
101 | | |
102 | | /// Extension trait for `LocalSpawn`. |
103 | | pub trait LocalSpawnExt: LocalSpawn { |
104 | | /// Spawns a task that polls the given future with output `()` to |
105 | | /// completion. |
106 | | /// |
107 | | /// This method returns a [`Result`] that contains a [`SpawnError`] if |
108 | | /// spawning fails. |
109 | | /// |
110 | | /// You can use [`spawn_with_handle`](SpawnExt::spawn_with_handle) if |
111 | | /// you want to spawn a future with output other than `()` or if you want |
112 | | /// to be able to await its completion. |
113 | | /// |
114 | | /// Note this method will eventually be replaced with the upcoming |
115 | | /// `Spawn::spawn` method which will take a `dyn Future` as input. |
116 | | /// Technical limitations prevent `Spawn::spawn` from being implemented |
117 | | /// today. Feel free to use this method in the meantime. |
118 | | /// |
119 | | /// ``` |
120 | | /// use futures::executor::LocalPool; |
121 | | /// use futures::task::LocalSpawnExt; |
122 | | /// |
123 | | /// let executor = LocalPool::new(); |
124 | | /// let spawner = executor.spawner(); |
125 | | /// |
126 | | /// let future = async { /* ... */ }; |
127 | | /// spawner.spawn_local(future).unwrap(); |
128 | | /// ``` |
129 | | #[cfg(feature = "alloc")] |
130 | 0 | fn spawn_local<Fut>(&self, future: Fut) -> Result<(), SpawnError> |
131 | 0 | where |
132 | 0 | Fut: Future<Output = ()> + 'static, |
133 | 0 | { |
134 | 0 | self.spawn_local_obj(LocalFutureObj::new(Box::new(future))) |
135 | 0 | } |
136 | | |
137 | | /// Spawns a task that polls the given future to completion and returns a |
138 | | /// future that resolves to the spawned future's output. |
139 | | /// |
140 | | /// This method returns a [`Result`] that contains a [`RemoteHandle`](crate::future::RemoteHandle), or, if |
141 | | /// spawning fails, a [`SpawnError`]. [`RemoteHandle`](crate::future::RemoteHandle) is a future that |
142 | | /// resolves to the output of the spawned future. |
143 | | /// |
144 | | /// ``` |
145 | | /// use futures::executor::LocalPool; |
146 | | /// use futures::task::LocalSpawnExt; |
147 | | /// |
148 | | /// let mut executor = LocalPool::new(); |
149 | | /// let spawner = executor.spawner(); |
150 | | /// |
151 | | /// let future = async { 1 }; |
152 | | /// let join_handle_fut = spawner.spawn_local_with_handle(future).unwrap(); |
153 | | /// assert_eq!(executor.run_until(join_handle_fut), 1); |
154 | | /// ``` |
155 | | #[cfg(feature = "channel")] |
156 | | #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] |
157 | | #[cfg(feature = "std")] |
158 | 0 | fn spawn_local_with_handle<Fut>( |
159 | 0 | &self, |
160 | 0 | future: Fut, |
161 | 0 | ) -> Result<RemoteHandle<Fut::Output>, SpawnError> |
162 | 0 | where |
163 | 0 | Fut: Future + 'static, |
164 | 0 | { |
165 | 0 | let (future, handle) = future.remote_handle(); |
166 | 0 | self.spawn_local(future)?; |
167 | 0 | Ok(handle) |
168 | 0 | } |
169 | | } |