aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/cpp/thread_manager
diff options
context:
space:
mode:
authorGravatar David Garcia Quintas <dgq@google.com>2017-07-14 18:35:50 -0700
committerGravatar David Garcia Quintas <dgq@google.com>2017-07-14 19:02:53 -0700
commitaef267b71e72d669d098e650bb74b2976c4fc8fb (patch)
tree62c7af0757f52762b3e59210bb4b3cc0f144f9ad /src/cpp/thread_manager
parent0c9ce722187d590f1e06fe0e822607077ba6ffa1 (diff)
Put thread creation and join under lock
Diffstat (limited to 'src/cpp/thread_manager')
-rw-r--r--src/cpp/thread_manager/thread_manager.cc23
-rw-r--r--src/cpp/thread_manager/thread_manager.h3
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_;
};