summaryrefslogtreecommitdiff
path: root/src/mongo/db/concurrency
diff options
context:
space:
mode:
authorVesselina Ratcheva <vesselina.ratcheva@10gen.com>2019-03-05 13:50:45 -0500
committerVesselina Ratcheva <vesselina.ratcheva@10gen.com>2019-03-06 12:16:11 -0500
commit1fe923eec6c301f554ec5a5cfb9a40ebf4318e13 (patch)
treeefd6b29a00d32358c3f295a57c79def4d70747ac /src/mongo/db/concurrency
parenta6a424f3961bec9e2311fa78a10e563d98ed2e88 (diff)
downloadmongo-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.cpp9
-rw-r--r--src/mongo/db/concurrency/lock_state.cpp8
-rw-r--r--src/mongo/db/concurrency/lock_state.h4
-rw-r--r--src/mongo/db/concurrency/locker.h10
-rw-r--r--src/mongo/db/concurrency/locker_noop.h4
-rw-r--r--src/mongo/db/concurrency/replication_state_transition_lock_guard.cpp16
-rw-r--r--src/mongo/db/concurrency/replication_state_transition_lock_guard.h11
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;
};