summaryrefslogtreecommitdiff
path: root/src/mongo/db/concurrency
diff options
context:
space:
mode:
authorVesselina Ratcheva <vesselina.ratcheva@10gen.com>2019-02-12 19:11:06 -0500
committerVesselina Ratcheva <vesselina.ratcheva@10gen.com>2019-03-04 18:59:23 -0500
commit6f3c3df4fc0abda76fd97e970ced4a01f0c48007 (patch)
tree45945a8d3bfd8ccead97946be88168b01298d817 /src/mongo/db/concurrency
parenta8ecb4270d7a5590c9509ff47c2670432122bf07 (diff)
downloadmongo-6f3c3df4fc0abda76fd97e970ced4a01f0c48007.tar.gz
SERVER-39154 Create a fail point to make it so if a LockManager lock cannot be acquired immediately, then the operation fails
Diffstat (limited to 'src/mongo/db/concurrency')
-rw-r--r--src/mongo/db/concurrency/lock_state.cpp13
-rw-r--r--src/mongo/db/concurrency/lock_state_test.cpp29
2 files changed, 42 insertions, 0 deletions
diff --git a/src/mongo/db/concurrency/lock_state.cpp b/src/mongo/db/concurrency/lock_state.cpp
index 0ce20b0aa3b..fc5457d3172 100644
--- a/src/mongo/db/concurrency/lock_state.cpp
+++ b/src/mongo/db/concurrency/lock_state.cpp
@@ -42,11 +42,15 @@
#include "mongo/util/background.h"
#include "mongo/util/concurrency/ticketholder.h"
#include "mongo/util/debug_util.h"
+#include "mongo/util/fail_point_service.h"
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
#include "mongo/util/scopeguard.h"
namespace mongo {
+
+MONGO_FAIL_POINT_DEFINE(failNonIntentLocksIfWaitNeeded);
+
namespace {
/**
@@ -474,6 +478,15 @@ void LockerImpl::lock(OperationContext* opCtx, ResourceId resId, LockMode mode,
invariant(result == LOCK_WAITING);
+ // This failpoint is used to time out non-intent locks if they cannot be granted immediately.
+ // Testing-only.
+ if (MONGO_FAIL_POINT(failNonIntentLocksIfWaitNeeded)) {
+ uassert(ErrorCodes::LockTimeout,
+ str::stream() << "Cannot immediately acquire lock '" << resId.toString()
+ << "'. Timing out due to failpoint.",
+ (mode == MODE_IS || mode == MODE_IX));
+ }
+
lockComplete(opCtx, resId, mode, deadline);
}
diff --git a/src/mongo/db/concurrency/lock_state_test.cpp b/src/mongo/db/concurrency/lock_state_test.cpp
index 115d1b5c42b..e6bc546b11f 100644
--- a/src/mongo/db/concurrency/lock_state_test.cpp
+++ b/src/mongo/db/concurrency/lock_state_test.cpp
@@ -39,6 +39,7 @@
#include "mongo/db/concurrency/lock_manager_test_help.h"
#include "mongo/db/concurrency/locker.h"
#include "mongo/unittest/unittest.h"
+#include "mongo/util/fail_point_service.h"
#include "mongo/util/log.h"
#include "mongo/util/timer.h"
@@ -120,6 +121,34 @@ TEST(LockerImpl, ConflictUpgradeWithTimeout) {
locker2.unlockGlobal();
}
+TEST(LockerImpl, FailPointInLockFailsNonIntentLocksIfTheyCannotBeImmediatelyGranted) {
+ // Granted MODE_X lock, fail incoming MODE_S and MODE_X.
+ const ResourceId resId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
+
+ LockerImpl locker1;
+ locker1.lockGlobal(MODE_IX);
+ locker1.lock(resId, MODE_X);
+
+ {
+ FailPointEnableBlock failWaitingNonPartitionedLocks("failNonIntentLocksIfWaitNeeded");
+
+ // MODE_S attempt.
+ LockerImpl locker2;
+ locker2.lockGlobal(MODE_IS);
+ ASSERT_THROWS_CODE(
+ locker2.lock(resId, MODE_S, Date_t::max()), DBException, ErrorCodes::LockTimeout);
+ locker2.unlockGlobal();
+
+ // MODE_X attempt.
+ LockerImpl locker3;
+ locker3.lockGlobal(MODE_IX);
+ ASSERT_THROWS_CODE(
+ locker3.lock(resId, MODE_X, Date_t::max()), DBException, ErrorCodes::LockTimeout);
+ locker3.unlockGlobal();
+ }
+
+ locker1.unlockGlobal();
+}
TEST(LockerImpl, ReadTransaction) {
LockerImpl locker;