@@ -31,6 +31,9 @@ use crate::platform::*;
3131use crate :: scope:: Scope ;
3232use crate :: signal:: Signal ;
3333use crate :: unwind;
34+ use crate :: AsyncMarker ;
35+ use crate :: FnOnceMarker ;
36+ use crate :: FutureMarker ;
3437
3538// -----------------------------------------------------------------------------
3639// Thread pool worker leases
@@ -491,22 +494,26 @@ impl ThreadPool {
491494// -----------------------------------------------------------------------------
492495// Generalized spawn trait
493496
494- pub trait Spawn < T > {
497+ /// Logic for spawning work onto a thread pool.
498+ ///
499+ /// This trait defines the behavior of [`ThreadPool::spawn`] for various types.
500+ pub trait Spawn < M > {
501+ /// The output returned by the spawn operation. This is usually either the
502+ /// empty type `()` or a `Task<T>`.
495503 type Output ;
496504
505+ /// Spawns work onto the thread pool.
497506 fn spawn ( self , thread_pool : & ' static ThreadPool , worker : Option < & Worker > ) -> Self :: Output ;
498507}
499508
500- struct FnOnceMarker ;
501-
502509impl < F > Spawn < FnOnceMarker > for F
503510where
504511 F : FnOnce ( & Worker ) + Send + ' static ,
505512{
506513 type Output = ( ) ;
507514
508515 #[ inline]
509- fn spawn ( self , _thread_pool : & ' static ThreadPool , worker : Option < & Worker > ) {
516+ fn spawn ( self , thread_pool : & ' static ThreadPool , worker : Option < & Worker > ) {
510517 // Allocate a new job on the heap to store the closure.
511518 let job = HeapJob :: new ( self ) ;
512519
@@ -523,13 +530,12 @@ where
523530 if let Some ( worker) = worker {
524531 worker. queue . push_back ( job_ref) ;
525532 } else {
526- todo ! ( ) ;
533+ let mut state = thread_pool. state . lock ( ) . unwrap ( ) ;
534+ state. shared_jobs . push_back ( job_ref) ;
527535 }
528536 }
529537}
530538
531- struct FutureMarker ;
532-
533539impl < Fut , T > Spawn < FutureMarker > for Fut
534540where
535541 Fut : Future < Output = T > + Send + ' static ,
@@ -588,8 +594,6 @@ where
588594 }
589595}
590596
591- struct AsyncMarker ;
592-
593597impl < Fn , Fut , T > Spawn < AsyncMarker > for Fn
594598where
595599 Fn : FnOnce ( ) -> Fut + Send + ' static ,
@@ -613,7 +617,7 @@ impl ThreadPool {
613617 ///
614618 /// See also: [`Worker::spawn`] and [`spawn`].
615619 #[ inline]
616- pub fn spawn < T , S : Spawn < T > > ( & ' static self , work : S ) -> <S as Spawn < T > >:: Output {
620+ pub fn spawn < M , S : Spawn < M > > ( & ' static self , work : S ) -> <S as Spawn < M > >:: Output {
617621 work. spawn ( self , None )
618622 }
619623
@@ -955,7 +959,7 @@ impl Worker {
955959 /// If you do not have access to a [`Worker`], you may call
956960 /// [`ThreadPool::spawn`] or simply [`spawn`].
957961 #[ inline]
958- pub fn spawn < T , S : Spawn < T > > ( & self , work : S ) -> <S as Spawn < T > >:: Output {
962+ pub fn spawn < M , S : Spawn < M > > ( & self , work : S ) -> <S as Spawn < M > >:: Output {
959963 work. spawn ( self . lease . thread_pool , Some ( self ) )
960964 }
961965
@@ -1104,7 +1108,7 @@ impl Worker {
11041108/// If there is no current thread pool, this panics.
11051109///
11061110/// See also: [`Worker::spawn`] and [`ThreadPool::spawn`].
1107- pub fn spawn < T , S : Spawn < T > > ( work : S ) -> <S as Spawn < T > >:: Output {
1111+ pub fn spawn < M , S : Spawn < M > > ( work : S ) -> <S as Spawn < M > >:: Output {
11081112 Worker :: with_current ( |worker| {
11091113 worker
11101114 . expect ( "attempt to call `forte::spawn` from outside a thread pool" )
@@ -1353,7 +1357,7 @@ mod tests {
13531357
13541358 THREAD_POOL . scope ( |scope| {
13551359 for _ in 0 ..NUM_JOBS {
1356- scope. spawn ( |_| {
1360+ scope. spawn ( |_: & Scope < ' _ > | {
13571361 THREAD_POOL . join (
13581362 |_| a. fetch_add ( 1 , Ordering :: Relaxed ) ,
13591363 |_| b. fetch_add ( 1 , Ordering :: Relaxed ) ,
0 commit comments