summaryrefslogtreecommitdiff
path: root/src/mongo/db/s/balancer
diff options
context:
space:
mode:
authorAlex Taskov <alex.taskov@mongodb.com>2020-01-08 16:17:51 +0000
committerevergreen <evergreen@mongodb.com>2020-01-08 16:17:51 +0000
commitdd3a688064d3c392b0bcdc500f19d9b40d4659d6 (patch)
treefc4ab7adcc560aec40bdf7956d071ffb291a4cd0 /src/mongo/db/s/balancer
parent9a04fb9267ac2828693911fe931169718f8d71d0 (diff)
downloadmongo-dd3a688064d3c392b0bcdc500f19d9b40d4659d6.tar.gz
SERVER-29829 Possible double call of std::thread::join through Balancer::waitForBalancerToStop
Diffstat (limited to 'src/mongo/db/s/balancer')
-rw-r--r--src/mongo/db/s/balancer/balancer.cpp27
-rw-r--r--src/mongo/db/s/balancer/balancer.h3
2 files changed, 14 insertions, 16 deletions
diff --git a/src/mongo/db/s/balancer/balancer.cpp b/src/mongo/db/s/balancer/balancer.cpp
index a81122592d6..25109941176 100644
--- a/src/mongo/db/s/balancer/balancer.cpp
+++ b/src/mongo/db/s/balancer/balancer.cpp
@@ -207,6 +207,7 @@ void Balancer::interruptBalancer() {
return;
_state = kStopping;
+ _thread.detach();
// Interrupt the balancer thread if it has been started. We are guaranteed that the operation
// context of that thread is still alive, because we hold the balancer mutex.
@@ -225,22 +226,9 @@ void Balancer::interruptBalancer() {
}
void Balancer::waitForBalancerToStop() {
- {
- stdx::lock_guard<Latch> scopedLock(_mutex);
- if (_state == kStopped)
- return;
-
- invariant(_state == kStopping);
- invariant(_thread.joinable());
- }
-
- _thread.join();
-
- stdx::lock_guard<Latch> scopedLock(_mutex);
- _state = kStopped;
- _thread = {};
+ stdx::unique_lock<Latch> scopedLock(_mutex);
- LOG(1) << "Balancer thread terminated";
+ _joinCond.wait(scopedLock, [this] { return _state == kStopped; });
}
void Balancer::joinCurrentRound(OperationContext* opCtx) {
@@ -313,6 +301,15 @@ void Balancer::report(OperationContext* opCtx, BSONObjBuilder* builder) {
}
void Balancer::_mainThread() {
+ ON_BLOCK_EXIT([this] {
+ stdx::lock_guard<Latch> scopedLock(_mutex);
+
+ _state = kStopped;
+ _joinCond.notify_all();
+
+ LOG(1) << "Balancer thread terminated";
+ });
+
Client::initThread("Balancer");
auto opCtx = cc().makeOperationContext();
auto shardingContext = Grid::get(opCtx.get());
diff --git a/src/mongo/db/s/balancer/balancer.h b/src/mongo/db/s/balancer/balancer.h
index bdb1551fa3f..e50e12ab06a 100644
--- a/src/mongo/db/s/balancer/balancer.h
+++ b/src/mongo/db/s/balancer/balancer.h
@@ -165,7 +165,7 @@ private:
*/
enum State {
kStopped, // kRunning
- kRunning, // kStopping
+ kRunning, // kStopping | kStopped
kStopping, // kStopped
};
@@ -226,6 +226,7 @@ private:
// The main balancer thread
stdx::thread _thread;
+ stdx::condition_variable _joinCond;
// The operation context of the main balancer thread. This value may only be available in the
// kRunning state and is used to force interrupt of any blocking calls made by the balancer