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