diff --git a/src/cpp/thread_manager/thread_manager.cc b/src/cpp/thread_manager/thread_manager.cc index 2b65352f797..b67cd4e716e 100644 --- a/src/cpp/thread_manager/thread_manager.cc +++ b/src/cpp/thread_manager/thread_manager.cc @@ -34,8 +34,16 @@ ThreadManager::WorkerThread::WorkerThread(ThreadManager* thd_mgr) thd_ = grpc_core::Thread( "grpcpp_sync_server", [](void* th) { static_cast(th)->Run(); }, - this); - thd_.Start(); + this, + &created_ + ); + if (!created_) { + gpr_log(GPR_ERROR, + "Could not create grpc_sync_server worker-thread" + ); + } else { + thd_.Start(); + } } void ThreadManager::WorkerThread::Run() { @@ -43,6 +51,11 @@ void ThreadManager::WorkerThread::Run() { thd_mgr_->MarkAsCompleted(this); } + +bool ThreadManager::WorkerThread::isCreated() { + return created_; +} + ThreadManager::WorkerThread::~WorkerThread() { // Don't join until the thread is fully constructed. thd_.Join(); @@ -177,7 +190,12 @@ void ThreadManager::MainWorkLoop() { } // Drop lock before spawning thread to avoid contention lock.Unlock(); - new WorkerThread(this); + WorkerThread* w = new WorkerThread(this); + if (!w->isCreated()) { + num_pollers_--; + num_threads_--; + resource_exhausted = true; + } } else if (num_pollers_ > 0) { // There is still at least some thread polling, so we can go on // even though we are below the number of pollers that we would diff --git a/src/cpp/thread_manager/thread_manager.h b/src/cpp/thread_manager/thread_manager.h index 62b1beebc37..d647399cb4e 100644 --- a/src/cpp/thread_manager/thread_manager.h +++ b/src/cpp/thread_manager/thread_manager.h @@ -124,6 +124,7 @@ class ThreadManager { WorkerThread(ThreadManager* thd_mgr); ~WorkerThread(); + bool isCreated(); private: // Calls thd_mgr_->MainWorkLoop() and once that completes, calls // thd_mgr_>MarkAsCompleted(this) to mark the thread as completed @@ -131,6 +132,7 @@ class ThreadManager { ThreadManager* const thd_mgr_; grpc_core::Thread thd_; + bool created_; }; // The main function in ThreadManager