diff options
author | Dianna <dianna.hohensee@10gen.com> | 2019-05-01 10:50:06 -0400 |
---|---|---|
committer | Dianna <dianna.hohensee@10gen.com> | 2019-05-13 17:08:05 -0400 |
commit | 3dbaffb7768951c185b48aa0bfd5a69dd99d4ec3 (patch) | |
tree | 66dadc92fd5a750b67911fc9d42b78af03c14587 /src/mongo/db/background.cpp | |
parent | dde091c07989ffaefc57705859abf6517beeeace (diff) | |
download | mongo-3dbaffb7768951c185b48aa0bfd5a69dd99d4ec3.tar.gz |
SERVER-40926 SERVER-40927 createIndexes cmd requests for indexes that are already being built wait for them to complete rather than return OK immediately
Diffstat (limited to 'src/mongo/db/background.cpp')
-rw-r--r-- | src/mongo/db/background.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/mongo/db/background.cpp b/src/mongo/db/background.cpp index 78d10eda93e..0f7b9cd7eea 100644 --- a/src/mongo/db/background.cpp +++ b/src/mongo/db/background.cpp @@ -34,6 +34,7 @@ #include <iostream> #include <string> +#include "mongo/db/operation_context.h" #include "mongo/stdx/condition_variable.h" #include "mongo/stdx/mutex.h" #include "mongo/stdx/thread.h" @@ -44,8 +45,6 @@ namespace mongo { -using std::shared_ptr; - namespace { class BgInfo { @@ -53,7 +52,7 @@ class BgInfo { BgInfo& operator=(const BgInfo&) = delete; public: - BgInfo() : _opsInProgCount(0) {} + BgInfo() : _opsInProgCount(0), _opRemovalsCount(0) {} void recordBegin(); int recordEnd(); @@ -63,9 +62,13 @@ public: return _opsInProgCount; } + void waitForAnOpRemoval(stdx::unique_lock<stdx::mutex>& lk, OperationContext* opCtx); + private: int _opsInProgCount; stdx::condition_variable _noOpsInProg; + int _opRemovalsCount; + stdx::condition_variable _waitForOpRemoval; }; typedef StringMap<std::shared_ptr<BgInfo>> BgInfoMap; @@ -83,6 +86,8 @@ void BgInfo::recordBegin() { int BgInfo::recordEnd() { dassert(_opsInProgCount > 0); --_opsInProgCount; + ++_opRemovalsCount; + _waitForOpRemoval.notify_all(); if (0 == _opsInProgCount) { _noOpsInProg.notify_all(); } @@ -94,6 +99,14 @@ void BgInfo::awaitNoBgOps(stdx::unique_lock<stdx::mutex>& lk) { _noOpsInProg.wait(lk); } +void BgInfo::waitForAnOpRemoval(stdx::unique_lock<stdx::mutex>& lk, OperationContext* opCtx) { + int startOpRemovalsCount = _opRemovalsCount; + + // Wait for an index build to finish. + opCtx->waitForConditionOrInterrupt( + _waitForOpRemoval, lk, [&] { return startOpRemovalsCount != _opRemovalsCount; }); +} + void recordBeginAndInsert(BgInfoMap& bgiMap, StringData key) { std::shared_ptr<BgInfo>& bgInfo = bgiMap[key]; if (!bgInfo) @@ -118,6 +131,16 @@ void awaitNoBgOps(stdx::unique_lock<stdx::mutex>& lk, BgInfoMap* bgiMap, StringD } // namespace +void BackgroundOperation::waitUntilAnIndexBuildFinishes(OperationContext* opCtx, StringData ns) { + stdx::unique_lock<stdx::mutex> lk(m); + std::shared_ptr<BgInfo> bgInfo = mapFindWithDefault(nsInProg, ns, std::shared_ptr<BgInfo>()); + if (!bgInfo) { + // There are no index builds in progress on the collection, so no need to wait. + return; + } + bgInfo->waitForAnOpRemoval(lk, opCtx); +} + bool BackgroundOperation::inProgForDb(StringData db) { stdx::lock_guard<stdx::mutex> lk(m); return dbsInProg.find(db) != dbsInProg.end(); |