From ccd9a414eb516e020fb74e042c90ed0128ffb890 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 16 Oct 2018 17:55:41 +0100 Subject: [PATCH] MCOL-1810 Fix hang on low core count Anything that links against joblist will spin up a threadpool upon startup. This includes the tools setConfig/getConfig. It is possible on a low core count machine or low CPU speed that the signal to the prune thread to shutdown is sent before the thread has completed startup when these quick-running tools are used. This fix adds a mutex so that spin up and shutdown can't happen at the same time as well as a stop watch in case we are shutting down when either the thread is running or we haven't fully started. --- utils/threadpool/threadpool.cpp | 4 ++++ utils/threadpool/threadpool.h | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/utils/threadpool/threadpool.cpp b/utils/threadpool/threadpool.cpp index 0b1546e98..602f868c4 100644 --- a/utils/threadpool/threadpool.cpp +++ b/utils/threadpool/threadpool.cpp @@ -55,6 +55,7 @@ ThreadPool::~ThreadPool() throw() { try { + boost::mutex::scoped_lock initLock(fInitMutex); stop(); } catch (...) @@ -64,6 +65,7 @@ ThreadPool::~ThreadPool() throw() void ThreadPool::init() { + boost::mutex::scoped_lock initLock(fInitMutex); fThreadCount = 0; fGeneralErrors = 0; fFunctorErrors = 0; @@ -89,6 +91,8 @@ void ThreadPool::pruneThread() while(true) { boost::system_time timeout = boost::get_system_time() + boost::posix_time::minutes(1); + if (fStop) + return; if (!fPruneThreadEnd.timed_wait(fPruneMutex, timeout)) { while(!fPruneThreads.empty()) diff --git a/utils/threadpool/threadpool.h b/utils/threadpool/threadpool.h index 1f0c6d0aa..4cb703c07 100644 --- a/utils/threadpool/threadpool.h +++ b/utils/threadpool/threadpool.h @@ -331,8 +331,9 @@ private: uint32_t waitingFunctorsSize; uint64_t fNextHandle; - std::string fName; // Optional to add a name to the pool for debugging. - bool fDebug; + std::string fName; // Optional to add a name to the pool for debugging. + bool fDebug; + boost::mutex fInitMutex; boost::mutex fPruneMutex; boost::condition fPruneThreadEnd; boost::thread* fPruneThread;