summaryrefslogtreecommitdiff
path: root/src/mongo/util
diff options
context:
space:
mode:
authorDianna Hohensee <dianna.hohensee@10gen.com>2017-07-26 12:42:14 -0400
committerDianna Hohensee <dianna.hohensee@10gen.com>2017-08-07 09:58:16 -0400
commit1cf5b5612d942e948c9a78115fc8980a10bbeca5 (patch)
treea81ca1c46eaa4566be85ce553e5c20fd392f540e /src/mongo/util
parentd90fcb7446cd6b68273f588c67a41b98d5c38268 (diff)
downloadmongo-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.cpp22
-rw-r--r--src/mongo/util/concurrency/thread_pool.h6
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.
*/