File tree Expand file tree Collapse file tree 2 files changed +45
-2
lines changed Expand file tree Collapse file tree 2 files changed +45
-2
lines changed Original file line number Diff line number Diff line change @@ -613,6 +613,16 @@ thread_local! {
613
613
static WORKER_THREAD_STATE : Cell <* const WorkerThread > = Cell :: new( ptr:: null( ) ) ;
614
614
}
615
615
616
+ impl Drop for WorkerThread {
617
+ fn drop ( & mut self ) {
618
+ // Undo `set_current`
619
+ WORKER_THREAD_STATE . with ( |t| {
620
+ assert ! ( t. get( ) . eq( & ( self as * const _) ) ) ;
621
+ t. set ( ptr:: null ( ) ) ;
622
+ } ) ;
623
+ }
624
+ }
625
+
616
626
impl WorkerThread {
617
627
/// Gets the `WorkerThread` index for the current thread; returns
618
628
/// NULL if this is not a worker thread. This pointer is valid
@@ -771,14 +781,14 @@ impl WorkerThread {
771
781
/// ////////////////////////////////////////////////////////////////////////
772
782
773
783
unsafe fn main_loop ( worker : Worker < JobRef > , registry : Arc < Registry > , index : usize ) {
774
- let worker_thread = WorkerThread {
784
+ let worker_thread = & WorkerThread {
775
785
worker,
776
786
fifo : JobFifo :: new ( ) ,
777
787
index,
778
788
rng : XorShift64Star :: new ( ) ,
779
789
registry : registry. clone ( ) ,
780
790
} ;
781
- WorkerThread :: set_current ( & worker_thread) ;
791
+ WorkerThread :: set_current ( worker_thread) ;
782
792
783
793
// let registry know we are ready to do work
784
794
registry. thread_infos [ index] . primed . set ( ) ;
Original file line number Diff line number Diff line change @@ -160,3 +160,36 @@ fn configuration() {
160
160
fn default_pool ( ) {
161
161
ThreadPoolBuilder :: default ( ) . build ( ) . unwrap ( ) ;
162
162
}
163
+
164
+ /// Test that custom spawned threads get their `WorkerThread` cleared once
165
+ /// the pool is done with them, allowing them to be used with rayon again
166
+ /// later. e.g. WebAssembly want to have their own pool of available threads.
167
+ #[ test]
168
+ fn cleared_current_thread ( ) -> Result < ( ) , ThreadPoolBuildError > {
169
+ let n_threads = 5 ;
170
+ let mut handles = vec ! [ ] ;
171
+ let pool = ThreadPoolBuilder :: new ( )
172
+ . num_threads ( n_threads)
173
+ . spawn_handler ( |thread| {
174
+ let handle = std:: thread:: spawn ( move || {
175
+ thread. run ( ) ;
176
+
177
+ // Afterward, the current thread shouldn't be set anymore.
178
+ assert_eq ! ( crate :: current_thread_index( ) , None ) ;
179
+ } ) ;
180
+ handles. push ( handle) ;
181
+ Ok ( ( ) )
182
+ } )
183
+ . build ( ) ?;
184
+ assert_eq ! ( handles. len( ) , n_threads) ;
185
+
186
+ pool. install ( || assert ! ( crate :: current_thread_index( ) . is_some( ) ) ) ;
187
+ drop ( pool) ;
188
+
189
+ // Wait for all threads to make their assertions and exit
190
+ for handle in handles {
191
+ handle. join ( ) . unwrap ( ) ;
192
+ }
193
+
194
+ Ok ( ( ) )
195
+ }
You can’t perform that action at this time.
0 commit comments