@@ -15,6 +15,7 @@ use std::fmt;
15
15
use std:: hash:: Hasher ;
16
16
use std:: io;
17
17
use std:: mem;
18
+ use std:: ops:: DerefMut ;
18
19
use std:: ptr;
19
20
#[ allow( deprecated) ]
20
21
use std:: sync:: atomic:: ATOMIC_USIZE_INIT ;
@@ -486,21 +487,26 @@ impl Registry {
486
487
OP : FnOnce ( & WorkerThread , bool ) -> R + Send ,
487
488
R : Send ,
488
489
{
489
- let mut latch = LockLatch :: new ( ) ;
490
-
491
- // This thread isn't a member of *any* thread pool, so just block.
492
- debug_assert ! ( WorkerThread :: current( ) . is_null( ) ) ;
493
- let job = StackJob :: new (
494
- |injected| {
495
- let worker_thread = WorkerThread :: current ( ) ;
496
- assert ! ( injected && !worker_thread. is_null( ) ) ;
497
- op ( & * worker_thread, true )
498
- } ,
499
- & mut latch,
500
- ) ;
501
- self . inject ( & [ job. as_job_ref ( ) ] ) ;
502
- job. latch . wait ( ) ;
503
- job. into_result ( )
490
+ LOCK_LATCH . with ( |l| {
491
+ // This should not panic since the latch is thread local and we are in the `cold` path.
492
+ // If `op` were to call another `ThreadPool::install` it would not end up here.
493
+ let mut latch = l. borrow_mut ( ) ;
494
+
495
+ // This thread isn't a member of *any* thread pool, so just block.
496
+ debug_assert ! ( WorkerThread :: current( ) . is_null( ) ) ;
497
+ let job = StackJob :: new (
498
+ |injected| {
499
+ let worker_thread = WorkerThread :: current ( ) ;
500
+ assert ! ( injected && !worker_thread. is_null( ) ) ;
501
+ op ( & * worker_thread, true )
502
+ } ,
503
+ latch. deref_mut ( ) ,
504
+ ) ;
505
+ self . inject ( & [ job. as_job_ref ( ) ] ) ;
506
+ job. latch . wait ( ) ;
507
+ job. latch . reset ( ) ; // Makes sure we can use the same latch again next time.
508
+ job. into_result ( )
509
+ } )
504
510
}
505
511
506
512
#[ cold]
@@ -613,6 +619,8 @@ pub(super) struct WorkerThread {
613
619
// for a RefCell<T> etc.
614
620
thread_local ! {
615
621
static WORKER_THREAD_STATE : Cell <* const WorkerThread > = Cell :: new( ptr:: null( ) ) ;
622
+
623
+ static LOCK_LATCH : RefCell <LockLatch > = RefCell :: new( LockLatch :: new( ) ) ;
616
624
}
617
625
618
626
impl Drop for WorkerThread {
0 commit comments