@@ -167,44 +167,48 @@ impl TaskPool {
167
167
let executor: & async_executor:: Executor = & * self . executor ;
168
168
let executor: & ' scope async_executor:: Executor = unsafe { mem:: transmute ( executor) } ;
169
169
170
- let fut = async move {
171
- let mut scope = Scope {
172
- executor,
173
- spawned : Vec :: new ( ) ,
174
- } ;
170
+ let mut scope = Scope {
171
+ executor,
172
+ spawned : Vec :: new ( ) ,
173
+ } ;
175
174
176
- f ( & mut scope) ;
175
+ f ( & mut scope) ;
177
176
178
- let mut results = Vec :: with_capacity ( scope. spawned . len ( ) ) ;
179
- for task in scope. spawned {
180
- results. push ( task. await ) ;
181
- }
177
+ if scope. spawned . len ( ) == 1 {
178
+ vec ! [ future:: block_on( & mut scope. spawned[ 0 ] ) ]
179
+ } else {
180
+ let fut = async move {
181
+ let mut results = Vec :: with_capacity ( scope. spawned . len ( ) ) ;
182
+ for task in scope. spawned {
183
+ results. push ( task. await ) ;
184
+ }
182
185
183
- results
184
- } ;
186
+ results
187
+ } ;
185
188
186
- // Pin the future on the stack.
187
- pin ! ( fut) ;
189
+ // Pin the future on the stack.
190
+ pin ! ( fut) ;
191
+
192
+ // SAFETY: This function blocks until all futures complete, so we do not read/write the
193
+ // data from futures outside of the 'scope lifetime. However, rust has no way of knowing
194
+ // this so we must convert to 'static here to appease the compiler as it is unable to
195
+ // validate safety.
196
+ let fut: Pin < & mut ( dyn Future < Output = Vec < T > > + Send ) > = fut;
197
+ let fut: Pin < & ' static mut ( dyn Future < Output = Vec < T > > + Send + ' static ) > =
198
+ unsafe { mem:: transmute ( fut) } ;
199
+
200
+ // The thread that calls scope() will participate in driving tasks in the pool forward
201
+ // until the tasks that are spawned by this scope() call complete. (If the caller of scope()
202
+ // happens to be a thread in this thread pool, and we only have one thread in the pool, then
203
+ // simply calling future::block_on(spawned) would deadlock.)
204
+ let mut spawned = self . executor . spawn ( fut) ;
205
+ loop {
206
+ if let Some ( result) = future:: block_on ( future:: poll_once ( & mut spawned) ) {
207
+ break result;
208
+ }
188
209
189
- // SAFETY: This function blocks until all futures complete, so we do not read/write the
190
- // data from futures outside of the 'scope lifetime. However, rust has no way of knowing
191
- // this so we must convert to 'static here to appease the compiler as it is unable to
192
- // validate safety.
193
- let fut: Pin < & mut ( dyn Future < Output = Vec < T > > + Send ) > = fut;
194
- let fut: Pin < & ' static mut ( dyn Future < Output = Vec < T > > + Send + ' static ) > =
195
- unsafe { mem:: transmute ( fut) } ;
196
-
197
- // The thread that calls scope() will participate in driving tasks in the pool forward
198
- // until the tasks that are spawned by this scope() call complete. (If the caller of scope()
199
- // happens to be a thread in this thread pool, and we only have one thread in the pool, then
200
- // simply calling future::block_on(spawned) would deadlock.)
201
- let mut spawned = self . executor . spawn ( fut) ;
202
- loop {
203
- if let Some ( result) = future:: block_on ( future:: poll_once ( & mut spawned) ) {
204
- break result;
210
+ self . executor . try_tick ( ) ;
205
211
}
206
-
207
- self . executor . try_tick ( ) ;
208
212
}
209
213
}
210
214
0 commit comments