| 
					
				 | 
			
			
				@@ -27,14 +27,23 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 namespace grpc { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ThreadManager::WorkerThread::WorkerThread(ThreadManager* thd_mgr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    : thd_mgr_(thd_mgr), thd_(&ThreadManager::WorkerThread::Run, this) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    : thd_mgr_(thd_mgr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Make thread creation exclusive with respect to its join happening in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // ~WorkerThread(). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::lock_guard<std::mutex> lock(wt_mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  thd_ = std::thread(&ThreadManager::WorkerThread::Run, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void ThreadManager::WorkerThread::Run() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   thd_mgr_->MainWorkLoop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   thd_mgr_->MarkAsCompleted(this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-ThreadManager::WorkerThread::~WorkerThread() { thd_.join(); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ThreadManager::WorkerThread::~WorkerThread() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Don't join until the thread is fully constructed. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::lock_guard<std::mutex> lock(wt_mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  thd_.join(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ThreadManager::ThreadManager(int min_pollers, int max_pollers) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     : shutdown_(false), 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -45,7 +54,7 @@ ThreadManager::ThreadManager(int min_pollers, int max_pollers) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ThreadManager::~ThreadManager() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    std::unique_lock<std::mutex> lock(mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    std::lock_guard<std::mutex> lock(mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GPR_ASSERT(num_threads_ == 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -60,22 +69,22 @@ void ThreadManager::Wait() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void ThreadManager::Shutdown() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  std::unique_lock<std::mutex> lock(mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::lock_guard<std::mutex> lock(mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   shutdown_ = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 bool ThreadManager::IsShutdown() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  std::unique_lock<std::mutex> lock(mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::lock_guard<std::mutex> lock(mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return shutdown_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void ThreadManager::MarkAsCompleted(WorkerThread* thd) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    std::unique_lock<std::mutex> list_lock(list_mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    std::lock_guard<std::mutex> list_lock(list_mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     completed_threads_.push_back(thd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  std::unique_lock<std::mutex> lock(mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::lock_guard<std::mutex> lock(mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   num_threads_--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (num_threads_ == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     shutdown_cv_.notify_one(); 
			 |