diff options
author | Vesselina Ratcheva <vesselina.ratcheva@10gen.com> | 2019-03-05 13:50:45 -0500 |
---|---|---|
committer | Vesselina Ratcheva <vesselina.ratcheva@10gen.com> | 2019-03-06 12:16:11 -0500 |
commit | 1fe923eec6c301f554ec5a5cfb9a40ebf4318e13 (patch) | |
tree | efd6b29a00d32358c3f295a57c79def4d70747ac /src/mongo/db/concurrency | |
parent | a6a424f3961bec9e2311fa78a10e563d98ed2e88 (diff) | |
download | mongo-1fe923eec6c301f554ec5a5cfb9a40ebf4318e13.tar.gz |
SERVER-39139 Make lock mode for ReplicationStateTransitionLockGuard configurable
Diffstat (limited to 'src/mongo/db/concurrency')
-rw-r--r-- | src/mongo/db/concurrency/d_concurrency_test.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/concurrency/lock_state.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/concurrency/lock_state.h | 4 | ||||
-rw-r--r-- | src/mongo/db/concurrency/locker.h | 10 | ||||
-rw-r--r-- | src/mongo/db/concurrency/locker_noop.h | 4 | ||||
-rw-r--r-- | src/mongo/db/concurrency/replication_state_transition_lock_guard.cpp | 16 | ||||
-rw-r--r-- | src/mongo/db/concurrency/replication_state_transition_lock_guard.h | 11 |
7 files changed, 33 insertions, 29 deletions
diff --git a/src/mongo/db/concurrency/d_concurrency_test.cpp b/src/mongo/db/concurrency/d_concurrency_test.cpp index 865a8bacb5f..504b3fbe4ab 100644 --- a/src/mongo/db/concurrency/d_concurrency_test.cpp +++ b/src/mongo/db/concurrency/d_concurrency_test.cpp @@ -2087,14 +2087,14 @@ TEST_F(DConcurrencyTestFixture, RSTLLockGuardTimeout) { auto secondOpCtx = clients[1].second.get(); // The first opCtx holds the RSTL. - repl::ReplicationStateTransitionLockGuard firstRSTL(firstOpCtx); + repl::ReplicationStateTransitionLockGuard firstRSTL(firstOpCtx, MODE_X); ASSERT_TRUE(firstRSTL.isLocked()); ASSERT_EQ(firstOpCtx->lockState()->getLockMode(resourceIdReplicationStateTransitionLock), MODE_X); // The second opCtx enqueues the lock request but cannot acquire it. repl::ReplicationStateTransitionLockGuard secondRSTL( - secondOpCtx, repl::ReplicationStateTransitionLockGuard::EnqueueOnly()); + secondOpCtx, MODE_X, repl::ReplicationStateTransitionLockGuard::EnqueueOnly()); ASSERT_FALSE(secondRSTL.isLocked()); // The second opCtx times out. @@ -2115,7 +2115,8 @@ TEST_F(DConcurrencyTestFixture, RSTLLockGuardEnqueueAndWait) { auto secondOpCtx = clients[1].second.get(); // The first opCtx holds the RSTL. - auto firstRSTL = stdx::make_unique<repl::ReplicationStateTransitionLockGuard>(firstOpCtx); + auto firstRSTL = + stdx::make_unique<repl::ReplicationStateTransitionLockGuard>(firstOpCtx, MODE_X); ASSERT_TRUE(firstRSTL->isLocked()); ASSERT_EQ(firstOpCtx->lockState()->getLockMode(resourceIdReplicationStateTransitionLock), MODE_X); @@ -2123,7 +2124,7 @@ TEST_F(DConcurrencyTestFixture, RSTLLockGuardEnqueueAndWait) { // The second opCtx enqueues the lock request but cannot acquire it. repl::ReplicationStateTransitionLockGuard secondRSTL( - secondOpCtx, repl::ReplicationStateTransitionLockGuard::EnqueueOnly()); + secondOpCtx, MODE_X, repl::ReplicationStateTransitionLockGuard::EnqueueOnly()); ASSERT_FALSE(secondRSTL.isLocked()); // The first opCtx unlocks so the second opCtx acquires it. diff --git a/src/mongo/db/concurrency/lock_state.cpp b/src/mongo/db/concurrency/lock_state.cpp index 80166ce716c..daecab8b66d 100644 --- a/src/mongo/db/concurrency/lock_state.cpp +++ b/src/mongo/db/concurrency/lock_state.cpp @@ -890,13 +890,13 @@ void LockerImpl::lockComplete(OperationContext* opCtx, unlockOnErrorGuard.dismiss(); } -LockResult LockerImpl::lockRSTLBegin(OperationContext* opCtx) { +LockResult LockerImpl::lockRSTLBegin(OperationContext* opCtx, LockMode mode) { invariant(!opCtx->lockState()->isLocked()); - return lockBegin(opCtx, resourceIdReplicationStateTransitionLock, MODE_X); + return lockBegin(opCtx, resourceIdReplicationStateTransitionLock, mode); } -void LockerImpl::lockRSTLComplete(OperationContext* opCtx, Date_t deadline) { - lockComplete(opCtx, resourceIdReplicationStateTransitionLock, MODE_X, deadline); +void LockerImpl::lockRSTLComplete(OperationContext* opCtx, LockMode mode, Date_t deadline) { + lockComplete(opCtx, resourceIdReplicationStateTransitionLock, mode, deadline); } void LockerImpl::releaseTicket() { diff --git a/src/mongo/db/concurrency/lock_state.h b/src/mongo/db/concurrency/lock_state.h index 44effcb124a..91c6e651d4f 100644 --- a/src/mongo/db/concurrency/lock_state.h +++ b/src/mongo/db/concurrency/lock_state.h @@ -145,8 +145,8 @@ public: virtual bool unlockGlobal(); - virtual LockResult lockRSTLBegin(OperationContext* opCtx); - virtual void lockRSTLComplete(OperationContext* opCtx, Date_t deadline); + virtual LockResult lockRSTLBegin(OperationContext* opCtx, LockMode mode); + virtual void lockRSTLComplete(OperationContext* opCtx, LockMode mode, Date_t deadline); virtual bool unlockRSTLforPrepare(); diff --git a/src/mongo/db/concurrency/locker.h b/src/mongo/db/concurrency/locker.h index 3c5653f39bc..ae951b4715b 100644 --- a/src/mongo/db/concurrency/locker.h +++ b/src/mongo/db/concurrency/locker.h @@ -196,20 +196,20 @@ public: virtual bool unlockGlobal() = 0; /** - * Requests the RSTL to be acquired in mode X. This should only be called inside - * ReplicationStateTransitionLockGuard. + * Requests the RSTL to be acquired in the requested mode (typically mode X) . This should only + * be called inside ReplicationStateTransitionLockGuard. * * See the comments for lockBegin/Complete for more information on the semantics. */ - virtual LockResult lockRSTLBegin(OperationContext* opCtx) = 0; + virtual LockResult lockRSTLBegin(OperationContext* opCtx, LockMode mode) = 0; /** - * Waits for the completion of acquiring the RSTL in mode X. This should only be called inside + * Waits for the completion of acquiring the RSTL. This should only be called inside * ReplicationStateTransitionLockGuard. * * It may throw an exception if it is interrupted. */ - virtual void lockRSTLComplete(OperationContext* opCtx, Date_t deadline) = 0; + virtual void lockRSTLComplete(OperationContext* opCtx, LockMode mode, Date_t deadline) = 0; /** * Unlocks the RSTL when the transaction becomes prepared. This is used to bypass two-phase diff --git a/src/mongo/db/concurrency/locker_noop.h b/src/mongo/db/concurrency/locker_noop.h index bb1dbfe5d86..7e46259cbc5 100644 --- a/src/mongo/db/concurrency/locker_noop.h +++ b/src/mongo/db/concurrency/locker_noop.h @@ -118,11 +118,11 @@ public: return false; } - virtual LockResult lockRSTLBegin(OperationContext* opCtx) { + virtual LockResult lockRSTLBegin(OperationContext* opCtx, LockMode mode) { MONGO_UNREACHABLE; } - virtual void lockRSTLComplete(OperationContext* opCtx, Date_t deadline) { + virtual void lockRSTLComplete(OperationContext* opCtx, LockMode mode, Date_t deadline) { MONGO_UNREACHABLE; } diff --git a/src/mongo/db/concurrency/replication_state_transition_lock_guard.cpp b/src/mongo/db/concurrency/replication_state_transition_lock_guard.cpp index 290018f7f8e..6224f7f5351 100644 --- a/src/mongo/db/concurrency/replication_state_transition_lock_guard.cpp +++ b/src/mongo/db/concurrency/replication_state_transition_lock_guard.cpp @@ -37,14 +37,16 @@ namespace mongo { namespace repl { -ReplicationStateTransitionLockGuard::ReplicationStateTransitionLockGuard(OperationContext* opCtx) - : ReplicationStateTransitionLockGuard(opCtx, EnqueueOnly()) { +ReplicationStateTransitionLockGuard::ReplicationStateTransitionLockGuard(OperationContext* opCtx, + LockMode mode) + : ReplicationStateTransitionLockGuard(opCtx, mode, EnqueueOnly()) { waitForLockUntil(Date_t::max()); } ReplicationStateTransitionLockGuard::ReplicationStateTransitionLockGuard(OperationContext* opCtx, + LockMode mode, EnqueueOnly) - : _opCtx(opCtx) { + : _opCtx(opCtx), _mode(mode) { _enqueueLock(); } @@ -65,8 +67,8 @@ void ReplicationStateTransitionLockGuard::waitForLockUntil(mongo::Date_t deadlin } _result = LOCK_INVALID; - // Wait for the completion of the lock request for the RSTL in mode X. - _opCtx->lockState()->lockRSTLComplete(_opCtx, deadline); + // Wait for the completion of the lock request for the RSTL. + _opCtx->lockState()->lockRSTLComplete(_opCtx, _mode, deadline); _result = LOCK_OK; } @@ -80,8 +82,8 @@ void ReplicationStateTransitionLockGuard::reacquire() { } void ReplicationStateTransitionLockGuard::_enqueueLock() { - // Enqueue a lock request for the RSTL in mode X. - _result = _opCtx->lockState()->lockRSTLBegin(_opCtx); + // Enqueue a lock request for the RSTL. + _result = _opCtx->lockState()->lockRSTLBegin(_opCtx, _mode); } void ReplicationStateTransitionLockGuard::_unlock() { diff --git a/src/mongo/db/concurrency/replication_state_transition_lock_guard.h b/src/mongo/db/concurrency/replication_state_transition_lock_guard.h index 9876a99e9d9..cbb23bb8a8d 100644 --- a/src/mongo/db/concurrency/replication_state_transition_lock_guard.h +++ b/src/mongo/db/concurrency/replication_state_transition_lock_guard.h @@ -52,15 +52,15 @@ public: class EnqueueOnly {}; /** - * Acquires the RSTL in mode X. + * Acquires the RSTL in the requested mode (typically mode X). */ - ReplicationStateTransitionLockGuard(OperationContext* opCtx); + ReplicationStateTransitionLockGuard(OperationContext* opCtx, LockMode mode); /** - * Enqueues RSTL in mode X but does not block on lock acquisition. + * Enqueues RSTL but does not block on lock acquisition. * Must call waitForLockUntil() to complete locking process. */ - ReplicationStateTransitionLockGuard(OperationContext* opCtx, EnqueueOnly); + ReplicationStateTransitionLockGuard(OperationContext* opCtx, LockMode mode, EnqueueOnly); ReplicationStateTransitionLockGuard(ReplicationStateTransitionLockGuard&&); ReplicationStateTransitionLockGuard& operator=(ReplicationStateTransitionLockGuard&&) = delete; @@ -73,7 +73,7 @@ public: void waitForLockUntil(Date_t deadline); /** - * Release and reacquire the RSTL in mode X. + * Release and reacquire the RSTL. */ void release(); void reacquire(); @@ -87,6 +87,7 @@ private: void _unlock(); OperationContext* const _opCtx; + LockMode _mode; LockResult _result; }; |