@@ -144,6 +144,12 @@ pub struct ThreadPoolBuilder<S = DefaultSpawn> {
144144 /// Closure invoked to spawn threads.
145145 spawn_handler : S ,
146146
147+ /// Closure invoked when starting computations in a thread.
148+ acquire_thread_handler : Option < Box < AcquireThreadHandler > > ,
149+
150+ /// Closure invoked when blocking in a thread.
151+ release_thread_handler : Option < Box < ReleaseThreadHandler > > ,
152+
147153 /// If false, worker threads will execute spawned jobs in a
148154 /// "depth-first" fashion. If true, they will do a "breadth-first"
149155 /// fashion. Depth-first is the default.
@@ -186,12 +192,22 @@ impl Default for ThreadPoolBuilder {
186192 start_handler : None ,
187193 exit_handler : None ,
188194 deadlock_handler : None ,
195+ acquire_thread_handler : None ,
196+ release_thread_handler : None ,
189197 spawn_handler : DefaultSpawn ,
190198 breadth_first : false ,
191199 }
192200 }
193201}
194202
203+ /// The type for a closure that gets invoked before starting computations in a thread.
204+ /// Note that this same closure may be invoked multiple times in parallel.
205+ type AcquireThreadHandler = dyn Fn ( ) + Send + Sync ;
206+
207+ /// The type for a closure that gets invoked before blocking in a thread.
208+ /// Note that this same closure may be invoked multiple times in parallel.
209+ type ReleaseThreadHandler = dyn Fn ( ) + Send + Sync ;
210+
195211impl ThreadPoolBuilder {
196212 /// Creates and returns a valid rayon thread pool builder, but does not initialize it.
197213 pub fn new ( ) -> Self {
@@ -292,7 +308,12 @@ impl ThreadPoolBuilder {
292308 Ok ( ( ) )
293309 } )
294310 . build ( ) ?;
295- Ok ( with_pool ( & pool) )
311+ let result = unwind:: halt_unwinding ( || with_pool ( & pool) ) ;
312+ pool. wait_until_stopped ( ) ;
313+ match result {
314+ Ok ( result) => Ok ( result) ,
315+ Err ( err) => unwind:: resume_unwinding ( err) ,
316+ }
296317 } ) ;
297318
298319 match result {
@@ -371,6 +392,8 @@ impl<S> ThreadPoolBuilder<S> {
371392 start_handler : self . start_handler ,
372393 exit_handler : self . exit_handler ,
373394 deadlock_handler : self . deadlock_handler ,
395+ acquire_thread_handler : self . acquire_thread_handler ,
396+ release_thread_handler : self . release_thread_handler ,
374397 breadth_first : self . breadth_first ,
375398 }
376399 }
@@ -529,6 +552,34 @@ impl<S> ThreadPoolBuilder<S> {
529552 self . breadth_first
530553 }
531554
555+ /// Takes the current acquire thread callback, leaving `None`.
556+ fn take_acquire_thread_handler ( & mut self ) -> Option < Box < AcquireThreadHandler > > {
557+ self . acquire_thread_handler . take ( )
558+ }
559+
560+ /// Set a callback to be invoked when starting computations in a thread.
561+ pub fn acquire_thread_handler < H > ( mut self , acquire_thread_handler : H ) -> Self
562+ where
563+ H : Fn ( ) + Send + Sync + ' static ,
564+ {
565+ self . acquire_thread_handler = Some ( Box :: new ( acquire_thread_handler) ) ;
566+ self
567+ }
568+
569+ /// Takes the current release thread callback, leaving `None`.
570+ fn take_release_thread_handler ( & mut self ) -> Option < Box < ReleaseThreadHandler > > {
571+ self . release_thread_handler . take ( )
572+ }
573+
574+ /// Set a callback to be invoked when blocking in thread.
575+ pub fn release_thread_handler < H > ( mut self , release_thread_handler : H ) -> Self
576+ where
577+ H : Fn ( ) + Send + Sync + ' static ,
578+ {
579+ self . release_thread_handler = Some ( Box :: new ( release_thread_handler) ) ;
580+ self
581+ }
582+
532583 /// Takes the current deadlock callback, leaving `None`.
533584 fn take_deadlock_handler ( & mut self ) -> Option < Box < DeadlockHandler > > {
534585 self . deadlock_handler . take ( )
@@ -699,6 +750,8 @@ impl<S> fmt::Debug for ThreadPoolBuilder<S> {
699750 ref deadlock_handler,
700751 ref start_handler,
701752 ref exit_handler,
753+ ref acquire_thread_handler,
754+ ref release_thread_handler,
702755 spawn_handler : _,
703756 ref breadth_first,
704757 } = * self ;
@@ -716,6 +769,8 @@ impl<S> fmt::Debug for ThreadPoolBuilder<S> {
716769 let deadlock_handler = deadlock_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
717770 let start_handler = start_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
718771 let exit_handler = exit_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
772+ let acquire_thread_handler = acquire_thread_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
773+ let release_thread_handler = release_thread_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
719774
720775 f. debug_struct ( "ThreadPoolBuilder" )
721776 . field ( "num_threads" , num_threads)
@@ -725,6 +780,8 @@ impl<S> fmt::Debug for ThreadPoolBuilder<S> {
725780 . field ( "deadlock_handler" , & deadlock_handler)
726781 . field ( "start_handler" , & start_handler)
727782 . field ( "exit_handler" , & exit_handler)
783+ . field ( "acquire_thread_handler" , & acquire_thread_handler)
784+ . field ( "release_thread_handler" , & release_thread_handler)
728785 . field ( "breadth_first" , & breadth_first)
729786 . finish ( )
730787 }
0 commit comments