summaryrefslogtreecommitdiff
path: root/src/mongo/db/concurrency/d_concurrency_test.cpp
diff options
context:
space:
mode:
authorSiyuan Zhou <siyuan.zhou@mongodb.com>2019-04-24 20:09:52 -0400
committerSiyuan Zhou <siyuan.zhou@mongodb.com>2019-05-03 20:10:27 -0400
commit4fb71c5a1c79b745ef56d53a8264ef5fdd202dda (patch)
treeaf44a7d5320b7ef6b2f7778ad52defbfc38defdb /src/mongo/db/concurrency/d_concurrency_test.cpp
parent51c1c3495e5583e3e570313eb0e0f68d304241e9 (diff)
downloadmongo-4fb71c5a1c79b745ef56d53a8264ef5fdd202dda.tar.gz
SERVER-40498 Side transaction keeps the same locker
Diffstat (limited to 'src/mongo/db/concurrency/d_concurrency_test.cpp')
-rw-r--r--src/mongo/db/concurrency/d_concurrency_test.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/mongo/db/concurrency/d_concurrency_test.cpp b/src/mongo/db/concurrency/d_concurrency_test.cpp
index cbe7d62bf35..3d400a9bceb 100644
--- a/src/mongo/db/concurrency/d_concurrency_test.cpp
+++ b/src/mongo/db/concurrency/d_concurrency_test.cpp
@@ -983,6 +983,36 @@ TEST_F(DConcurrencyTestFixture,
MODE_NONE);
}
+TEST_F(DConcurrencyTestFixture, FailedGlobalLockShouldUnlockRSTLOnlyOnce) {
+ auto clients = makeKClientsWithLockers(2);
+ auto opCtx1 = clients[0].second.get();
+ auto opCtx2 = clients[1].second.get();
+
+ auto resourceRSTL = resourceIdReplicationStateTransitionLock;
+
+ // Take the exclusive lock with the first caller.
+ Lock::GlobalLock globalLock(opCtx1, MODE_X);
+
+ opCtx2->lockState()->beginWriteUnitOfWork();
+ // Set a max timeout on the second caller that will override provided lock request
+ // deadlines.
+ // Then requesting a lock with Date_t::max() should cause a LockTimeout error to be thrown.
+ opCtx2->lockState()->setMaxLockTimeout(Milliseconds(100));
+
+ ASSERT_THROWS_CODE(
+ Lock::GlobalLock(opCtx2, MODE_IX, Date_t::max(), Lock::InterruptBehavior::kThrow),
+ DBException,
+ ErrorCodes::LockTimeout);
+ auto opCtx2Locker = static_cast<LockerImpl*>(opCtx2->lockState());
+ // GlobalLock failed, but the RSTL should be successfully acquired and pending unlocked.
+ ASSERT(opCtx2Locker->getRequestsForTest().find(resourceIdGlobal).finished());
+ ASSERT_EQ(opCtx2Locker->getRequestsForTest().find(resourceRSTL).objAddr()->unlockPending, 1U);
+ ASSERT_EQ(opCtx2Locker->getRequestsForTest().find(resourceRSTL).objAddr()->recursiveCount, 1U);
+ opCtx2->lockState()->endWriteUnitOfWork();
+ ASSERT_EQ(opCtx1->lockState()->getLockMode(resourceRSTL), MODE_IX);
+ ASSERT_EQ(opCtx2->lockState()->getLockMode(resourceRSTL), MODE_NONE);
+}
+
TEST_F(DConcurrencyTestFixture, DBLockWaitIsInterruptible) {
auto clients = makeKClientsWithLockers(2);
auto opCtx1 = clients[0].second.get();