30
30
31
31
use std:: future:: Future ;
32
32
use std:: pin:: Pin ;
33
+ use std:: sync:: Arc ;
33
34
use std:: task:: { Context , Poll } ;
34
35
use std:: time:: Duration ;
35
36
@@ -72,7 +73,7 @@ scoped_thread_local!(static LOCAL_EX: LocalExecutor);
72
73
/// ```
73
74
#[ derive( Debug ) ]
74
75
pub struct Executor {
75
- ex : multitask:: Executor ,
76
+ ex : Arc < multitask:: Executor > ,
76
77
}
77
78
78
79
impl Executor {
@@ -81,13 +82,29 @@ impl Executor {
81
82
/// # Examples
82
83
///
83
84
/// ```
84
- /// use async_executor::LocalExecutor ;
85
+ /// use async_executor::Executor ;
85
86
///
86
- /// let local_ex = LocalExecutor ::new();
87
+ /// let ex = Executor ::new();
87
88
/// ```
88
89
pub fn new ( ) -> Executor {
89
90
Executor {
90
- ex : multitask:: Executor :: new ( ) ,
91
+ ex : Arc :: new ( multitask:: Executor :: new ( ) ) ,
92
+ }
93
+ }
94
+
95
+ /// Creates a spawner for this executor.
96
+ ///
97
+ /// # Examples
98
+ ///
99
+ /// ```
100
+ /// use async_executor::Executor;
101
+ ///
102
+ /// let ex = Executor::new();
103
+ /// let spawner = ex.spawner();
104
+ /// ```
105
+ pub fn spawner ( & self ) -> Spawner {
106
+ Spawner {
107
+ ex : self . ex . clone ( ) ,
91
108
}
92
109
}
93
110
@@ -184,6 +201,62 @@ impl Default for Executor {
184
201
}
185
202
}
186
203
204
+ /// A spawner for a multi-threaded executor.
205
+ #[ derive( Debug ) ]
206
+ pub struct Spawner {
207
+ ex : Arc < multitask:: Executor > ,
208
+ }
209
+
210
+ impl Spawner {
211
+ /// Gets a spawner for the current multi-threaded executor.
212
+ ///
213
+ /// If called from an [`Executor`], returns its [`Spawner`].
214
+ ///
215
+ /// Otherwise, this method panics.
216
+ ///
217
+ /// # Examples
218
+ ///
219
+ /// ```
220
+ /// use async_executor::{Executor, Spawner};
221
+ ///
222
+ /// let ex = Executor::new();
223
+ ///
224
+ /// ex.run(async {
225
+ /// let spawner = Spawner::current();
226
+ /// let task = spawner.spawn(async { 1 + 2 });
227
+ /// assert_eq!(task.await, 3);
228
+ /// });
229
+ /// ```
230
+ pub fn current ( ) -> Spawner {
231
+ if EX . is_set ( ) {
232
+ EX . with ( |ex| ex. spawner ( ) )
233
+ } else {
234
+ panic ! ( "`Spawner::current()` must be called from an `Executor`" )
235
+ }
236
+ }
237
+
238
+ /// Spawns a task onto the executor.
239
+ ///
240
+ /// # Examples
241
+ ///
242
+ /// ```
243
+ /// use async_executor::Executor;
244
+ ///
245
+ /// let ex = Executor::new();
246
+ /// let spawner = ex.spawner();
247
+ ///
248
+ /// let task = spawner.spawn(async {
249
+ /// println!("Hello world");
250
+ /// });
251
+ /// ```
252
+ pub fn spawn < T : Send + ' static > (
253
+ & self ,
254
+ future : impl Future < Output = T > + Send + ' static ,
255
+ ) -> Task < T > {
256
+ Task ( self . ex . spawn ( future) )
257
+ }
258
+ }
259
+
187
260
/// Single-threaded executor.
188
261
///
189
262
/// The executor can only be run on the thread that created it.
0 commit comments