@@ -159,6 +159,12 @@ pub struct ThreadPoolBuilder<S = DefaultSpawn> {
159159 /// Closure invoked to spawn threads.
160160 spawn_handler : S ,
161161
162+ /// Closure invoked when starting computations in a thread.
163+ acquire_thread_handler : Option < Box < AcquireThreadHandler > > ,
164+
165+ /// Closure invoked when blocking in a thread.
166+ release_thread_handler : Option < Box < ReleaseThreadHandler > > ,
167+
162168 /// If false, worker threads will execute spawned jobs in a
163169 /// "depth-first" fashion. If true, they will do a "breadth-first"
164170 /// fashion. Depth-first is the default.
@@ -201,12 +207,22 @@ impl Default for ThreadPoolBuilder {
201207 start_handler : None ,
202208 exit_handler : None ,
203209 deadlock_handler : None ,
210+ acquire_thread_handler : None ,
211+ release_thread_handler : None ,
204212 spawn_handler : DefaultSpawn ,
205213 breadth_first : false ,
206214 }
207215 }
208216}
209217
218+ /// The type for a closure that gets invoked before starting computations in a thread.
219+ /// Note that this same closure may be invoked multiple times in parallel.
220+ type AcquireThreadHandler = dyn Fn ( ) + Send + Sync ;
221+
222+ /// The type for a closure that gets invoked before blocking in a thread.
223+ /// Note that this same closure may be invoked multiple times in parallel.
224+ type ReleaseThreadHandler = dyn Fn ( ) + Send + Sync ;
225+
210226impl ThreadPoolBuilder {
211227 /// Creates and returns a valid rayon thread pool builder, but does not initialize it.
212228 pub fn new ( ) -> Self {
@@ -309,7 +325,12 @@ impl ThreadPoolBuilder {
309325 Ok ( ( ) )
310326 } )
311327 . build ( ) ?;
312- Ok ( with_pool ( & pool) )
328+ let result = unwind:: halt_unwinding ( || with_pool ( & pool) ) ;
329+ pool. wait_until_stopped ( ) ;
330+ match result {
331+ Ok ( result) => Ok ( result) ,
332+ Err ( err) => unwind:: resume_unwinding ( err) ,
333+ }
313334 } ) ;
314335
315336 match result {
@@ -388,6 +409,8 @@ impl<S> ThreadPoolBuilder<S> {
388409 start_handler : self . start_handler ,
389410 exit_handler : self . exit_handler ,
390411 deadlock_handler : self . deadlock_handler ,
412+ acquire_thread_handler : self . acquire_thread_handler ,
413+ release_thread_handler : self . release_thread_handler ,
391414 breadth_first : self . breadth_first ,
392415 }
393416 }
@@ -546,6 +569,34 @@ impl<S> ThreadPoolBuilder<S> {
546569 self . breadth_first
547570 }
548571
572+ /// Takes the current acquire thread callback, leaving `None`.
573+ fn take_acquire_thread_handler ( & mut self ) -> Option < Box < AcquireThreadHandler > > {
574+ self . acquire_thread_handler . take ( )
575+ }
576+
577+ /// Set a callback to be invoked when starting computations in a thread.
578+ pub fn acquire_thread_handler < H > ( mut self , acquire_thread_handler : H ) -> Self
579+ where
580+ H : Fn ( ) + Send + Sync + ' static ,
581+ {
582+ self . acquire_thread_handler = Some ( Box :: new ( acquire_thread_handler) ) ;
583+ self
584+ }
585+
586+ /// Takes the current release thread callback, leaving `None`.
587+ fn take_release_thread_handler ( & mut self ) -> Option < Box < ReleaseThreadHandler > > {
588+ self . release_thread_handler . take ( )
589+ }
590+
591+ /// Set a callback to be invoked when blocking in thread.
592+ pub fn release_thread_handler < H > ( mut self , release_thread_handler : H ) -> Self
593+ where
594+ H : Fn ( ) + Send + Sync + ' static ,
595+ {
596+ self . release_thread_handler = Some ( Box :: new ( release_thread_handler) ) ;
597+ self
598+ }
599+
549600 /// Takes the current deadlock callback, leaving `None`.
550601 fn take_deadlock_handler ( & mut self ) -> Option < Box < DeadlockHandler > > {
551602 self . deadlock_handler . take ( )
@@ -716,6 +767,8 @@ impl<S> fmt::Debug for ThreadPoolBuilder<S> {
716767 ref deadlock_handler,
717768 ref start_handler,
718769 ref exit_handler,
770+ ref acquire_thread_handler,
771+ ref release_thread_handler,
719772 spawn_handler : _,
720773 ref breadth_first,
721774 } = * self ;
@@ -733,6 +786,8 @@ impl<S> fmt::Debug for ThreadPoolBuilder<S> {
733786 let deadlock_handler = deadlock_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
734787 let start_handler = start_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
735788 let exit_handler = exit_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
789+ let acquire_thread_handler = acquire_thread_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
790+ let release_thread_handler = release_thread_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
736791
737792 f. debug_struct ( "ThreadPoolBuilder" )
738793 . field ( "num_threads" , num_threads)
@@ -742,6 +797,8 @@ impl<S> fmt::Debug for ThreadPoolBuilder<S> {
742797 . field ( "deadlock_handler" , & deadlock_handler)
743798 . field ( "start_handler" , & start_handler)
744799 . field ( "exit_handler" , & exit_handler)
800+ . field ( "acquire_thread_handler" , & acquire_thread_handler)
801+ . field ( "release_thread_handler" , & release_thread_handler)
745802 . field ( "breadth_first" , & breadth_first)
746803 . finish ( )
747804 }
0 commit comments