Skip to content
Snippets Groups Projects
Commit aef267b7 authored by David Garcia Quintas's avatar David Garcia Quintas
Browse files

Put thread creation and join under lock

parent 0c9ce722
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