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! {
613613 static WORKER_THREAD_STATE : Cell <* const WorkerThread > = Cell :: new( ptr:: null( ) ) ;
614614}
615615
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+
616626impl WorkerThread {
617627 /// Gets the `WorkerThread` index for the current thread; returns
618628 /// NULL if this is not a worker thread. This pointer is valid
@@ -771,14 +781,14 @@ impl WorkerThread {
771781/// ////////////////////////////////////////////////////////////////////////
772782
773783unsafe fn main_loop ( worker : Worker < JobRef > , registry : Arc < Registry > , index : usize ) {
774- let worker_thread = WorkerThread {
784+ let worker_thread = & WorkerThread {
775785 worker,
776786 fifo : JobFifo :: new ( ) ,
777787 index,
778788 rng : XorShift64Star :: new ( ) ,
779789 registry : registry. clone ( ) ,
780790 } ;
781- WorkerThread :: set_current ( & worker_thread) ;
791+ WorkerThread :: set_current ( worker_thread) ;
782792
783793 // let registry know we are ready to do work
784794 registry. thread_infos [ index] . primed . set ( ) ;
Original file line number Diff line number Diff line change @@ -160,3 +160,36 @@ fn configuration() {
160160fn default_pool ( ) {
161161 ThreadPoolBuilder :: default ( ) . build ( ) . unwrap ( ) ;
162162}
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