Coverage Report

Created: 2025-08-26 06:20

/rust/registry/src/index.crates.io-6f17d22bba15001f/futures-task-0.3.31/src/spawn.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{FutureObj, LocalFutureObj};
2
use core::fmt;
3
4
/// The `Spawn` trait allows for pushing futures onto an executor that will
5
/// run them to completion.
6
pub trait Spawn {
7
    /// Spawns a future that will be run to completion.
8
    ///
9
    /// # Errors
10
    ///
11
    /// The executor may be unable to spawn tasks. Spawn errors should
12
    /// represent relatively rare scenarios, such as the executor
13
    /// having been shut down so that it is no longer able to accept
14
    /// tasks.
15
    fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError>;
16
17
    /// Determines whether the executor is able to spawn new tasks.
18
    ///
19
    /// This method will return `Ok` when the executor is *likely*
20
    /// (but not guaranteed) to accept a subsequent spawn attempt.
21
    /// Likewise, an `Err` return means that `spawn` is likely, but
22
    /// not guaranteed, to yield an error.
23
    #[inline]
24
0
    fn status(&self) -> Result<(), SpawnError> {
25
0
        Ok(())
26
0
    }
27
}
28
29
/// The `LocalSpawn` is similar to [`Spawn`], but allows spawning futures
30
/// that don't implement `Send`.
31
pub trait LocalSpawn {
32
    /// Spawns a future that will be run to completion.
33
    ///
34
    /// # Errors
35
    ///
36
    /// The executor may be unable to spawn tasks. Spawn errors should
37
    /// represent relatively rare scenarios, such as the executor
38
    /// having been shut down so that it is no longer able to accept
39
    /// tasks.
40
    fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError>;
41
42
    /// Determines whether the executor is able to spawn new tasks.
43
    ///
44
    /// This method will return `Ok` when the executor is *likely*
45
    /// (but not guaranteed) to accept a subsequent spawn attempt.
46
    /// Likewise, an `Err` return means that `spawn` is likely, but
47
    /// not guaranteed, to yield an error.
48
    #[inline]
49
0
    fn status_local(&self) -> Result<(), SpawnError> {
50
0
        Ok(())
51
0
    }
52
}
53
54
/// An error that occurred during spawning.
55
pub struct SpawnError {
56
    _priv: (),
57
}
58
59
impl fmt::Debug for SpawnError {
60
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61
0
        f.debug_tuple("SpawnError").field(&"shutdown").finish()
62
0
    }
63
}
64
65
impl fmt::Display for SpawnError {
66
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67
0
        write!(f, "Executor is shutdown")
68
0
    }
69
}
70
71
#[cfg(feature = "std")]
72
impl std::error::Error for SpawnError {}
73
74
impl SpawnError {
75
    /// Spawning failed because the executor has been shut down.
76
0
    pub fn shutdown() -> Self {
77
0
        Self { _priv: () }
78
0
    }
79
80
    /// Check whether spawning failed to the executor being shut down.
81
0
    pub fn is_shutdown(&self) -> bool {
82
0
        true
83
0
    }
84
}
85
86
impl<Sp: ?Sized + Spawn> Spawn for &Sp {
87
0
    fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
88
0
        Sp::spawn_obj(self, future)
89
0
    }
90
91
0
    fn status(&self) -> Result<(), SpawnError> {
92
0
        Sp::status(self)
93
0
    }
94
}
95
96
impl<Sp: ?Sized + Spawn> Spawn for &mut Sp {
97
0
    fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
98
0
        Sp::spawn_obj(self, future)
99
0
    }
100
101
0
    fn status(&self) -> Result<(), SpawnError> {
102
0
        Sp::status(self)
103
0
    }
104
}
105
106
impl<Sp: ?Sized + LocalSpawn> LocalSpawn for &Sp {
107
0
    fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> {
108
0
        Sp::spawn_local_obj(self, future)
109
0
    }
110
111
0
    fn status_local(&self) -> Result<(), SpawnError> {
112
0
        Sp::status_local(self)
113
0
    }
114
}
115
116
impl<Sp: ?Sized + LocalSpawn> LocalSpawn for &mut Sp {
117
0
    fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> {
118
0
        Sp::spawn_local_obj(self, future)
119
0
    }
120
121
0
    fn status_local(&self) -> Result<(), SpawnError> {
122
0
        Sp::status_local(self)
123
0
    }
124
}
125
126
#[cfg(feature = "alloc")]
127
mod if_alloc {
128
    use super::*;
129
    use alloc::{boxed::Box, rc::Rc};
130
131
    impl<Sp: ?Sized + Spawn> Spawn for Box<Sp> {
132
0
        fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
133
0
            (**self).spawn_obj(future)
134
0
        }
135
136
0
        fn status(&self) -> Result<(), SpawnError> {
137
0
            (**self).status()
138
0
        }
139
    }
140
141
    impl<Sp: ?Sized + LocalSpawn> LocalSpawn for Box<Sp> {
142
0
        fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> {
143
0
            (**self).spawn_local_obj(future)
144
0
        }
145
146
0
        fn status_local(&self) -> Result<(), SpawnError> {
147
0
            (**self).status_local()
148
0
        }
149
    }
150
151
    impl<Sp: ?Sized + Spawn> Spawn for Rc<Sp> {
152
0
        fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
153
0
            (**self).spawn_obj(future)
154
0
        }
155
156
0
        fn status(&self) -> Result<(), SpawnError> {
157
0
            (**self).status()
158
0
        }
159
    }
160
161
    impl<Sp: ?Sized + LocalSpawn> LocalSpawn for Rc<Sp> {
162
0
        fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> {
163
0
            (**self).spawn_local_obj(future)
164
0
        }
165
166
0
        fn status_local(&self) -> Result<(), SpawnError> {
167
0
            (**self).status_local()
168
0
        }
169
    }
170
171
    #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
172
    impl<Sp: ?Sized + Spawn> Spawn for alloc::sync::Arc<Sp> {
173
0
        fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
174
0
            (**self).spawn_obj(future)
175
0
        }
176
177
0
        fn status(&self) -> Result<(), SpawnError> {
178
0
            (**self).status()
179
0
        }
180
    }
181
182
    #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
183
    impl<Sp: ?Sized + LocalSpawn> LocalSpawn for alloc::sync::Arc<Sp> {
184
0
        fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> {
185
0
            (**self).spawn_local_obj(future)
186
0
        }
187
188
0
        fn status_local(&self) -> Result<(), SpawnError> {
189
0
            (**self).status_local()
190
0
        }
191
    }
192
}