diff options
Diffstat (limited to 'src/mongo/db/concurrency/d_concurrency.cpp')
-rw-r--r-- | src/mongo/db/concurrency/d_concurrency.cpp | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/src/mongo/db/concurrency/d_concurrency.cpp b/src/mongo/db/concurrency/d_concurrency.cpp index fd1f809cc94..ab0e4d3866c 100644 --- a/src/mongo/db/concurrency/d_concurrency.cpp +++ b/src/mongo/db/concurrency/d_concurrency.cpp @@ -139,12 +139,14 @@ bool Lock::ResourceMutex::isAtLeastReadLocked(Locker* locker) { Lock::GlobalLock::GlobalLock(OperationContext* opCtx, LockMode lockMode, Date_t deadline, - InterruptBehavior behavior) + InterruptBehavior behavior, + bool skipRSTLLock) : _opCtx(opCtx), _result(LOCK_INVALID), _pbwm(opCtx->lockState(), resourceIdParallelBatchWriterMode), _fcvLock(opCtx->lockState(), resourceIdFeatureCompatibilityVersion), _interruptBehavior(behavior), + _skipRSTLLock(skipRSTLLock), _isOutermostLock(!opCtx->lockState()->isLocked()) { _opCtx->lockState()->getFlowControlTicket(_opCtx, lockMode); @@ -167,17 +169,14 @@ Lock::GlobalLock::GlobalLock(OperationContext* opCtx, } }); - _opCtx->lockState()->lock( - _opCtx, resourceIdReplicationStateTransitionLock, MODE_IX, deadline); - - auto unlockRSTL = makeGuard( - [this] { _opCtx->lockState()->unlock(resourceIdReplicationStateTransitionLock); }); - _result = LOCK_INVALID; - _opCtx->lockState()->lockGlobal(_opCtx, lockMode, deadline); + if (skipRSTLLock) { + _takeGlobalLockOnly(lockMode, deadline); + } else { + _takeGlobalAndRSTLLocks(lockMode, deadline); + } _result = LOCK_OK; - unlockRSTL.dismiss(); unlockFCVLock.dismiss(); unlockPBWM.dismiss(); } catch (const ExceptionForCat<ErrorCategory::Interruption>&) { @@ -189,12 +188,27 @@ Lock::GlobalLock::GlobalLock(OperationContext* opCtx, _opCtx->lockState()->setGlobalLockTakenInMode(acquiredLockMode); } +void Lock::GlobalLock::_takeGlobalLockOnly(LockMode lockMode, Date_t deadline) { + _opCtx->lockState()->lockGlobal(_opCtx, lockMode, deadline); +} + +void Lock::GlobalLock::_takeGlobalAndRSTLLocks(LockMode lockMode, Date_t deadline) { + _opCtx->lockState()->lock(_opCtx, resourceIdReplicationStateTransitionLock, MODE_IX, deadline); + auto unlockRSTL = makeGuard( + [this] { _opCtx->lockState()->unlock(resourceIdReplicationStateTransitionLock); }); + + _opCtx->lockState()->lockGlobal(_opCtx, lockMode, deadline); + + unlockRSTL.dismiss(); +} + Lock::GlobalLock::GlobalLock(GlobalLock&& otherLock) : _opCtx(otherLock._opCtx), _result(otherLock._result), _pbwm(std::move(otherLock._pbwm)), _fcvLock(std::move(otherLock._fcvLock)), _interruptBehavior(otherLock._interruptBehavior), + _skipRSTLLock(otherLock._skipRSTLLock), _isOutermostLock(otherLock._isOutermostLock) { // Mark as moved so the destructor doesn't invalidate the newly-constructed lock. otherLock._result = LOCK_INVALID; |