diff options
author | Dianna Hohensee <dianna.hohensee@10gen.com> | 2017-07-26 12:42:14 -0400 |
---|---|---|
committer | Dianna Hohensee <dianna.hohensee@10gen.com> | 2017-08-07 09:58:16 -0400 |
commit | 1cf5b5612d942e948c9a78115fc8980a10bbeca5 (patch) | |
tree | a81ca1c46eaa4566be85ce553e5c20fd392f540e /src/mongo/util | |
parent | d90fcb7446cd6b68273f588c67a41b98d5c38268 (diff) | |
download | mongo-1cf5b5612d942e948c9a78115fc8980a10bbeca5.tar.gz |
SERVER-30254 Make ThreadPool::join finish remaining tasks on a pristine thread instead of inline
Diffstat (limited to 'src/mongo/util')
-rw-r--r-- | src/mongo/util/concurrency/thread_pool.cpp | 22 | ||||
-rw-r--r-- | src/mongo/util/concurrency/thread_pool.h | 6 |
2 files changed, 26 insertions, 2 deletions
diff --git a/src/mongo/util/concurrency/thread_pool.cpp b/src/mongo/util/concurrency/thread_pool.cpp index 5ea024725e0..279d85bc85d 100644 --- a/src/mongo/util/concurrency/thread_pool.cpp +++ b/src/mongo/util/concurrency/thread_pool.cpp @@ -157,8 +157,10 @@ void ThreadPool::_join_inlock(stdx::unique_lock<stdx::mutex>* lk) { }); _setState_inlock(joining); ++_numIdleThreads; - while (!_pendingTasks.empty()) { - _doOneTask(lk); + if (!_pendingTasks.empty()) { + lk->unlock(); + _drainPendingTasks(); + lk->lock(); } --_numIdleThreads; ThreadList threadsToJoin; @@ -172,6 +174,22 @@ void ThreadPool::_join_inlock(stdx::unique_lock<stdx::mutex>* lk) { _setState_inlock(shutdownComplete); } +void ThreadPool::_drainPendingTasks() { + // Tasks cannot be run inline because they can create OperationContexts and the join() caller + // may already have one associated with the thread. + stdx::thread cleanThread = stdx::thread([&] { + const std::string threadName = str::stream() << _options.threadNamePrefix + << _nextThreadId++; + setThreadName(threadName); + _options.onCreateThread(threadName); + while (!_pendingTasks.empty()) { + stdx::unique_lock<stdx::mutex> lock(_mutex); + _doOneTask(&lock); + } + }); + cleanThread.join(); +} + Status ThreadPool::schedule(Task task) { stdx::lock_guard<stdx::mutex> lk(_mutex); switch (_state) { diff --git a/src/mongo/util/concurrency/thread_pool.h b/src/mongo/util/concurrency/thread_pool.h index 982e11e250b..d88787fa484 100644 --- a/src/mongo/util/concurrency/thread_pool.h +++ b/src/mongo/util/concurrency/thread_pool.h @@ -186,6 +186,12 @@ private: void _join_inlock(stdx::unique_lock<stdx::mutex>* lk); /** + * Runs the remaining tasks on a new thread as part of the join process, blocking until + * complete. Caller must not hold the mutex! + */ + void _drainPendingTasks(); + + /** * Executes one task from _pendingTasks. "lk" must own _mutex, and _pendingTasks must have at * least one entry. */ |