diff options
author | David Garcia Quintas <dgq@google.com> | 2017-07-14 18:35:50 -0700 |
---|---|---|
committer | David Garcia Quintas <dgq@google.com> | 2017-07-14 19:02:53 -0700 |
commit | aef267b71e72d669d098e650bb74b2976c4fc8fb (patch) | |
tree | 62c7af0757f52762b3e59210bb4b3cc0f144f9ad | |
parent | 0c9ce722187d590f1e06fe0e822607077ba6ffa1 (diff) |
Put thread creation and join under lock
-rw-r--r-- | src/cpp/thread_manager/thread_manager.cc | 23 | ||||
-rw-r--r-- | src/cpp/thread_manager/thread_manager.h | 3 |
2 files changed, 18 insertions, 8 deletions
diff --git a/src/cpp/thread_manager/thread_manager.cc b/src/cpp/thread_manager/thread_manager.cc index c0e860d147..3610aa9013 100644 --- a/src/cpp/thread_manager/thread_manager.cc +++ b/src/cpp/thread_manager/thread_manager.cc @@ -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(); diff --git a/src/cpp/thread_manager/thread_manager.h b/src/cpp/thread_manager/thread_manager.h index d714ef3bb7..a206e0bd8a 100644 --- a/src/cpp/thread_manager/thread_manager.h +++ b/src/cpp/thread_manager/thread_manager.h @@ -100,7 +100,8 @@ class ThreadManager { // thd_mgr_>MarkAsCompleted(this) to mark the thread as completed void Run(); - ThreadManager* thd_mgr_; + ThreadManager* const thd_mgr_; + std::mutex wt_mu_; std::thread thd_; }; |