@@ -144,6 +144,12 @@ pub struct ThreadPoolBuilder<S = DefaultSpawn> {
144
144
/// Closure invoked to spawn threads.
145
145
spawn_handler : S ,
146
146
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
+
147
153
/// If false, worker threads will execute spawned jobs in a
148
154
/// "depth-first" fashion. If true, they will do a "breadth-first"
149
155
/// fashion. Depth-first is the default.
@@ -186,12 +192,22 @@ impl Default for ThreadPoolBuilder {
186
192
start_handler : None ,
187
193
exit_handler : None ,
188
194
deadlock_handler : None ,
195
+ acquire_thread_handler : None ,
196
+ release_thread_handler : None ,
189
197
spawn_handler : DefaultSpawn ,
190
198
breadth_first : false ,
191
199
}
192
200
}
193
201
}
194
202
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
+
195
211
impl ThreadPoolBuilder {
196
212
/// Creates and returns a valid rayon thread pool builder, but does not initialize it.
197
213
pub fn new ( ) -> Self {
@@ -292,7 +308,12 @@ impl ThreadPoolBuilder {
292
308
Ok ( ( ) )
293
309
} )
294
310
. 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
+ }
296
317
} ) ;
297
318
298
319
match result {
@@ -371,6 +392,8 @@ impl<S> ThreadPoolBuilder<S> {
371
392
start_handler : self . start_handler ,
372
393
exit_handler : self . exit_handler ,
373
394
deadlock_handler : self . deadlock_handler ,
395
+ acquire_thread_handler : self . acquire_thread_handler ,
396
+ release_thread_handler : self . release_thread_handler ,
374
397
breadth_first : self . breadth_first ,
375
398
}
376
399
}
@@ -529,6 +552,34 @@ impl<S> ThreadPoolBuilder<S> {
529
552
self . breadth_first
530
553
}
531
554
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
+
532
583
/// Takes the current deadlock callback, leaving `None`.
533
584
fn take_deadlock_handler ( & mut self ) -> Option < Box < DeadlockHandler > > {
534
585
self . deadlock_handler . take ( )
@@ -699,6 +750,8 @@ impl<S> fmt::Debug for ThreadPoolBuilder<S> {
699
750
ref deadlock_handler,
700
751
ref start_handler,
701
752
ref exit_handler,
753
+ ref acquire_thread_handler,
754
+ ref release_thread_handler,
702
755
spawn_handler : _,
703
756
ref breadth_first,
704
757
} = * self ;
@@ -716,6 +769,8 @@ impl<S> fmt::Debug for ThreadPoolBuilder<S> {
716
769
let deadlock_handler = deadlock_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
717
770
let start_handler = start_handler. as_ref ( ) . map ( |_| ClosurePlaceholder ) ;
718
771
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 ) ;
719
774
720
775
f. debug_struct ( "ThreadPoolBuilder" )
721
776
. field ( "num_threads" , num_threads)
@@ -725,6 +780,8 @@ impl<S> fmt::Debug for ThreadPoolBuilder<S> {
725
780
. field ( "deadlock_handler" , & deadlock_handler)
726
781
. field ( "start_handler" , & start_handler)
727
782
. field ( "exit_handler" , & exit_handler)
783
+ . field ( "acquire_thread_handler" , & acquire_thread_handler)
784
+ . field ( "release_thread_handler" , & release_thread_handler)
728
785
. field ( "breadth_first" , & breadth_first)
729
786
. finish ( )
730
787
}
0 commit comments