Skip to content
Snippets Groups Projects
Commit ee3fddb6 authored by David G. Quintas's avatar David G. Quintas Committed by GitHub
Browse files

Merge pull request #11837 from dgquintas/thread_manager_join

Put thread creation and join under lock
parents 9a48199d aef267b7
No related branches found
No related tags found
No related merge requests found
...@@ -27,14 +27,23 @@ ...@@ -27,14 +27,23 @@
namespace grpc { namespace grpc {
ThreadManager::WorkerThread::WorkerThread(ThreadManager* thd_mgr) 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() { void ThreadManager::WorkerThread::Run() {
thd_mgr_->MainWorkLoop(); thd_mgr_->MainWorkLoop();
thd_mgr_->MarkAsCompleted(this); 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) ThreadManager::ThreadManager(int min_pollers, int max_pollers)
: shutdown_(false), : shutdown_(false),
...@@ -45,7 +54,7 @@ ThreadManager::ThreadManager(int min_pollers, int max_pollers) ...@@ -45,7 +54,7 @@ ThreadManager::ThreadManager(int min_pollers, int max_pollers)
ThreadManager::~ThreadManager() { ThreadManager::~ThreadManager() {
{ {
std::unique_lock<std::mutex> lock(mu_); std::lock_guard<std::mutex> lock(mu_);
GPR_ASSERT(num_threads_ == 0); GPR_ASSERT(num_threads_ == 0);
} }
...@@ -60,22 +69,22 @@ void ThreadManager::Wait() { ...@@ -60,22 +69,22 @@ void ThreadManager::Wait() {
} }
void ThreadManager::Shutdown() { void ThreadManager::Shutdown() {
std::unique_lock<std::mutex> lock(mu_); std::lock_guard<std::mutex> lock(mu_);
shutdown_ = true; shutdown_ = true;
} }
bool ThreadManager::IsShutdown() { bool ThreadManager::IsShutdown() {
std::unique_lock<std::mutex> lock(mu_); std::lock_guard<std::mutex> lock(mu_);
return shutdown_; return shutdown_;
} }
void ThreadManager::MarkAsCompleted(WorkerThread* thd) { 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); completed_threads_.push_back(thd);
} }
std::unique_lock<std::mutex> lock(mu_); std::lock_guard<std::mutex> lock(mu_);
num_threads_--; num_threads_--;
if (num_threads_ == 0) { if (num_threads_ == 0) {
shutdown_cv_.notify_one(); shutdown_cv_.notify_one();
......
...@@ -100,7 +100,8 @@ class ThreadManager { ...@@ -100,7 +100,8 @@ class ThreadManager {
// thd_mgr_>MarkAsCompleted(this) to mark the thread as completed // thd_mgr_>MarkAsCompleted(this) to mark the thread as completed
void Run(); void Run();
ThreadManager* thd_mgr_; ThreadManager* const thd_mgr_;
std::mutex wt_mu_;
std::thread thd_; std::thread thd_;
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment