@@ -159,6 +159,12 @@ pub struct ThreadPoolBuilder<S = DefaultSpawn> {
159
159
/// Closure invoked to spawn threads.
160
160
spawn_handler : S ,
161
161
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
+
162
168
/// If false, worker threads will execute spawned jobs in a
163
169
/// "depth-first" fashion. If true, they will do a "breadth-first"
164
170
/// fashion. Depth-first is the default.
@@ -201,12 +207,22 @@ impl Default for ThreadPoolBuilder {
201
207
start_handler : None ,
202
208
exit_handler : None ,
203
209
deadlock_handler : None ,
210
+ acquire_thread_handler : None ,
211
+ release_thread_handler : None ,
204
212
spawn_handler : DefaultSpawn ,
205
213
breadth_first : false ,
206
214
}
207
215
}
208
216
}
209
217
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
+
210
226
impl ThreadPoolBuilder {
211
227
/// Creates and returns a valid rayon thread pool builder, but does not initialize it.
212
228
pub fn new ( ) -> Self {
@@ -309,7 +325,12 @@ impl ThreadPoolBuilder {
309
325
Ok ( ( ) )
310
326
} )
311
327
. 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
+ }
313
334
} ) ;
314
335
315
336
match result {
@@ -388,6 +409,8 @@ impl<S> ThreadPoolBuilder<S> {
388
409
start_handler : self . start_handler ,
389
410
exit_handler : self . exit_handler ,
390
411
deadlock_handler : self . deadlock_handler ,
412
+ acquire_thread_handler : self . acquire_thread_handler ,
413
+ release_thread_handler : self . release_thread_handler ,
391
414
breadth_first : self . breadth_first ,
392
415
}
393
416
}
@@ -546,6 +569,34 @@ impl<S> ThreadPoolBuilder<S> {
546
569
self . breadth_first
547
570
}
548
571
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
+
549
600
/// Takes the current deadlock callback, leaving `None`.
550
601
fn take_deadlock_handler ( & mut self ) -> Option < Box < DeadlockHandler > > {
551
602
self . deadlock_handler . take ( )
@@ -716,6 +767,8 @@ impl<S> fmt::Debug for ThreadPoolBuilder<S> {
716
767
ref deadlock_handler,
717
768
ref start_handler,
718
769
ref exit_handler,
770
+ ref acquire_thread_handler,
771
+ ref release_thread_handler,
719
772
spawn_handler : _,
720
773
ref breadth_first,
721
774
} = * self ;
@@ -733,6 +786,8 @@ impl<S> fmt::Debug for ThreadPoolBuilder<S> {
733
786
let deadlock_handler = deadlock_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
734
787
let start_handler = start_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
735
788
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 ) ;
736
791
737
792
f. debug_struct ( "ThreadPoolBuilder" )
738
793
. field ( "num_threads" , num_threads)
@@ -742,6 +797,8 @@ impl<S> fmt::Debug for ThreadPoolBuilder<S> {
742
797
. field ( "deadlock_handler" , & deadlock_handler)
743
798
. field ( "start_handler" , & start_handler)
744
799
. field ( "exit_handler" , & exit_handler)
800
+ . field ( "acquire_thread_handler" , & acquire_thread_handler)
801
+ . field ( "release_thread_handler" , & release_thread_handler)
745
802
. field ( "breadth_first" , & breadth_first)
746
803
. finish ( )
747
804
}
0 commit comments