@@ -3,7 +3,7 @@ use std::{
3
3
marker:: PhantomData ,
4
4
mem,
5
5
sync:: Arc ,
6
- thread:: { self , JoinHandle } ,
6
+ thread:: { self , JoinHandle } , pin :: Pin ,
7
7
} ;
8
8
9
9
use async_task:: FallibleTask ;
@@ -279,8 +279,23 @@ impl TaskPool {
279
279
// Pin the futures on the stack.
280
280
pin ! ( get_results) ;
281
281
282
+ // SAFETY: This function blocks until all futures complete, so we do not read/write
283
+ // the data from futures outside of the 'scope lifetime. However,
284
+ // rust has no way of knowing this so we must convert to 'static
285
+ // here to appease the compiler as it is unable to validate safety.
286
+ let get_results: Pin < & mut ( dyn Future < Output = Vec < T > > + ' static + Send ) > = get_results;
287
+ let get_results: Pin < & ' static mut ( dyn Future < Output = Vec < T > > + ' static + Send ) > =
288
+ unsafe { mem:: transmute ( get_results) } ;
289
+
290
+ // The thread that calls scope() will participate in driving tasks in the pool
291
+ // forward until the tasks that are spawned by this scope() call
292
+ // complete. (If the caller of scope() happens to be a thread in
293
+ // this thread pool, and we only have one thread in the pool, then
294
+ // simply calling future::block_on(spawned) would deadlock.)
295
+ let mut spawned = task_scope_executor. spawn ( get_results) ;
296
+
282
297
loop {
283
- if let Some ( result) = future:: block_on ( future:: poll_once ( & mut get_results ) ) {
298
+ if let Some ( result) = future:: block_on ( future:: poll_once ( & mut spawned ) ) {
284
299
break result;
285
300
} ;
286
301
0 commit comments