1
1
use std:: {
2
2
future:: Future ,
3
3
mem,
4
- pin:: Pin ,
5
4
sync:: Arc ,
6
5
thread:: { self , JoinHandle } ,
7
6
} ;
8
7
9
- use futures_lite:: { future, pin , FutureExt } ;
8
+ use futures_lite:: { future, FutureExt } ;
10
9
11
10
use crate :: { Task , TaskGroup } ;
12
11
@@ -303,8 +302,13 @@ impl TaskPool {
303
302
let shutdown_rx = shutdown_rx. clone ( ) ;
304
303
make_thread_builder ( & builder, "Compute" , i)
305
304
. spawn ( move || {
305
+ let future = async {
306
+ loop {
307
+ compute. tick ( ) . await ;
308
+ }
309
+ } ;
306
310
// Use unwrap_err because we expect a Closed error
307
- future:: block_on ( compute . run ( shutdown_rx. recv ( ) ) ) . unwrap_err ( ) ;
311
+ future:: block_on ( shutdown_rx. recv ( ) . or ( future ) ) . unwrap_err ( ) ;
308
312
} )
309
313
. expect ( "Failed to spawn thread." )
310
314
} )
@@ -322,7 +326,7 @@ impl TaskPool {
322
326
}
323
327
} ;
324
328
// Use unwrap_err because we expect a Closed error
325
- future:: block_on ( future . or ( shutdown_rx. recv ( ) ) ) . unwrap_err ( ) ;
329
+ future:: block_on ( shutdown_rx. recv ( ) . or ( future ) ) . unwrap_err ( ) ;
326
330
} )
327
331
. expect ( "Failed to spawn thread." )
328
332
} )
@@ -341,7 +345,7 @@ impl TaskPool {
341
345
}
342
346
} ;
343
347
// Use unwrap_err because we expect a Closed error
344
- future:: block_on ( future . or ( shutdown_rx. recv ( ) ) ) . unwrap_err ( ) ;
348
+ future:: block_on ( shutdown_rx. recv ( ) . or ( future ) ) . unwrap_err ( ) ;
345
349
} )
346
350
. expect ( "Failed to spawn thread." )
347
351
} )
@@ -436,12 +440,8 @@ impl TaskPool {
436
440
437
441
f ( & mut scope) ;
438
442
439
- if scope. spawned . is_empty ( ) {
440
- Vec :: default ( )
441
- } else if scope. spawned . len ( ) == 1 {
442
- vec ! [ future:: block_on( & mut scope. spawned[ 0 ] ) ]
443
- } else {
444
- let fut = async move {
443
+ future:: block_on ( async move {
444
+ let get_results = async move {
445
445
let mut results = Vec :: with_capacity ( scope. spawned . len ( ) ) ;
446
446
for task in scope. spawned {
447
447
results. push ( task. await ) ;
@@ -450,32 +450,14 @@ impl TaskPool {
450
450
results
451
451
} ;
452
452
453
- // Pin the futures on the stack.
454
- pin ! ( fut) ;
455
-
456
- // SAFETY: This function blocks until all futures complete, so we do not read/write
457
- // the data from futures outside of the 'scope lifetime. However,
458
- // rust has no way of knowing this so we must convert to 'static
459
- // here to appease the compiler as it is unable to validate safety.
460
- let fut: Pin < & mut ( dyn Future < Output = Vec < T > > ) > = fut;
461
- let fut: Pin < & ' static mut ( dyn Future < Output = Vec < T > > + ' static ) > =
462
- unsafe { mem:: transmute ( fut) } ;
463
-
464
- // The thread that calls scope() will participate in driving tasks in the pool
465
- // forward until the tasks that are spawned by this scope() call
466
- // complete. (If the caller of scope() happens to be a thread in
467
- // this thread pool, and we only have one thread in the pool, then
468
- // simply calling future::block_on(spawned) would deadlock.)
469
- let mut spawned = local_executor. spawn ( fut) ;
470
- loop {
471
- if let Some ( result) = future:: block_on ( future:: poll_once ( & mut spawned) ) {
472
- break result;
473
- } ;
474
-
475
- executor. try_tick ( ) ;
476
- local_executor. try_tick ( ) ;
477
- }
478
- }
453
+ let tick_forever = async move {
454
+ loop {
455
+ local_executor. tick ( ) . or ( executor. tick ( ) ) . await ;
456
+ }
457
+ } ;
458
+
459
+ get_results. or ( tick_forever) . await
460
+ } )
479
461
} )
480
462
}
481
463
0 commit comments