diff options
author | Alex Taskov <alex.taskov@mongodb.com> | 2020-01-08 16:17:51 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2020-01-08 16:17:51 +0000 |
commit | dd3a688064d3c392b0bcdc500f19d9b40d4659d6 (patch) | |
tree | fc4ab7adcc560aec40bdf7956d071ffb291a4cd0 /src/mongo/db/s/balancer | |
parent | 9a04fb9267ac2828693911fe931169718f8d71d0 (diff) | |
download | mongo-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.cpp | 27 | ||||
-rw-r--r-- | src/mongo/db/s/balancer/balancer.h | 3 |
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 |