/rust/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.21/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 | | /// # if cfg!(miri) { return; } // https://github.com/rust-lang/miri/issues/1038 |
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 | | #[cfg(feature = "alloc")] |
47 | 0 | fn spawn<Fut>(&self, future: Fut) -> Result<(), SpawnError> |
48 | 0 | where |
49 | 0 | Fut: Future<Output = ()> + Send + 'static, |
50 | 0 | { |
51 | 0 | self.spawn_obj(FutureObj::new(Box::new(future))) |
52 | 0 | } |
53 | | |
54 | | /// Spawns a task that polls the given future to completion and returns a |
55 | | /// future that resolves to the spawned future's output. |
56 | | /// |
57 | | /// This method returns a [`Result`] that contains a [`RemoteHandle`](crate::future::RemoteHandle), or, if |
58 | | /// spawning fails, a [`SpawnError`]. [`RemoteHandle`](crate::future::RemoteHandle) is a future that |
59 | | /// resolves to the output of the spawned future. |
60 | | /// |
61 | | /// ``` |
62 | | /// # if cfg!(miri) { return; } // https://github.com/rust-lang/miri/issues/1038 |
63 | | /// use futures::executor::{block_on, ThreadPool}; |
64 | | /// use futures::future; |
65 | | /// use futures::task::SpawnExt; |
66 | | /// |
67 | | /// let executor = ThreadPool::new().unwrap(); |
68 | | /// |
69 | | /// let future = future::ready(1); |
70 | | /// let join_handle_fut = executor.spawn_with_handle(future).unwrap(); |
71 | | /// assert_eq!(block_on(join_handle_fut), 1); |
72 | | /// ``` |
73 | | #[cfg(feature = "channel")] |
74 | | #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] |
75 | | #[cfg(feature = "std")] |
76 | 0 | fn spawn_with_handle<Fut>(&self, future: Fut) -> Result<RemoteHandle<Fut::Output>, SpawnError> |
77 | 0 | where |
78 | 0 | Fut: Future + Send + 'static, |
79 | 0 | Fut::Output: Send, |
80 | 0 | { |
81 | 0 | let (future, handle) = future.remote_handle(); |
82 | 0 | self.spawn(future)?; |
83 | 0 | Ok(handle) |
84 | 0 | } |
85 | | |
86 | | /// Wraps a [`Spawn`] and makes it usable as a futures 0.1 `Executor`. |
87 | | /// Requires the `compat` feature to enable. |
88 | | #[cfg(feature = "compat")] |
89 | | #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] |
90 | | fn compat(self) -> Compat<Self> |
91 | | where |
92 | | Self: Sized, |
93 | | { |
94 | | Compat::new(self) |
95 | | } |
96 | | } |
97 | | |
98 | | /// Extension trait for `LocalSpawn`. |
99 | | pub trait LocalSpawnExt: LocalSpawn { |
100 | | /// Spawns a task that polls the given future with output `()` to |
101 | | /// completion. |
102 | | /// |
103 | | /// This method returns a [`Result`] that contains a [`SpawnError`] if |
104 | | /// spawning fails. |
105 | | /// |
106 | | /// You can use [`spawn_with_handle`](SpawnExt::spawn_with_handle) if |
107 | | /// you want to spawn a future with output other than `()` or if you want |
108 | | /// to be able to await its completion. |
109 | | /// |
110 | | /// Note this method will eventually be replaced with the upcoming |
111 | | /// `Spawn::spawn` method which will take a `dyn Future` as input. |
112 | | /// Technical limitations prevent `Spawn::spawn` from being implemented |
113 | | /// today. Feel free to use this method in the meantime. |
114 | | /// |
115 | | /// ``` |
116 | | /// use futures::executor::LocalPool; |
117 | | /// use futures::task::LocalSpawnExt; |
118 | | /// |
119 | | /// let executor = LocalPool::new(); |
120 | | /// let spawner = executor.spawner(); |
121 | | /// |
122 | | /// let future = async { /* ... */ }; |
123 | | /// spawner.spawn_local(future).unwrap(); |
124 | | /// ``` |
125 | | #[cfg(feature = "alloc")] |
126 | 0 | fn spawn_local<Fut>(&self, future: Fut) -> Result<(), SpawnError> |
127 | 0 | where |
128 | 0 | Fut: Future<Output = ()> + 'static, |
129 | 0 | { |
130 | 0 | self.spawn_local_obj(LocalFutureObj::new(Box::new(future))) |
131 | 0 | } |
132 | | |
133 | | /// Spawns a task that polls the given future to completion and returns a |
134 | | /// future that resolves to the spawned future's output. |
135 | | /// |
136 | | /// This method returns a [`Result`] that contains a [`RemoteHandle`](crate::future::RemoteHandle), or, if |
137 | | /// spawning fails, a [`SpawnError`]. [`RemoteHandle`](crate::future::RemoteHandle) is a future that |
138 | | /// resolves to the output of the spawned future. |
139 | | /// |
140 | | /// ``` |
141 | | /// # if cfg!(miri) { return; } // https://github.com/rust-lang/miri/issues/1038 |
142 | | /// use futures::executor::LocalPool; |
143 | | /// use futures::task::LocalSpawnExt; |
144 | | /// |
145 | | /// let mut executor = LocalPool::new(); |
146 | | /// let spawner = executor.spawner(); |
147 | | /// |
148 | | /// let future = async { 1 }; |
149 | | /// let join_handle_fut = spawner.spawn_local_with_handle(future).unwrap(); |
150 | | /// assert_eq!(executor.run_until(join_handle_fut), 1); |
151 | | /// ``` |
152 | | #[cfg(feature = "channel")] |
153 | | #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] |
154 | | #[cfg(feature = "std")] |
155 | 0 | fn spawn_local_with_handle<Fut>( |
156 | 0 | &self, |
157 | 0 | future: Fut, |
158 | 0 | ) -> Result<RemoteHandle<Fut::Output>, SpawnError> |
159 | 0 | where |
160 | 0 | Fut: Future + 'static, |
161 | 0 | { |
162 | 0 | let (future, handle) = future.remote_handle(); |
163 | 0 | self.spawn_local(future)?; |
164 | 0 | Ok(handle) |
165 | 0 | } |
166 | | } |