summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordi Olivares Provencio <jordi.olivares-provencio@mongodb.com>2022-04-20 13:27:01 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-04-20 13:53:12 +0000
commite399b6676c5fc11df61e9b8ca4c27a2f7fc1e584 (patch)
tree0494726144eda7a7bbbec93649467a8d84f724d0
parentf08cda52ec0e3cbe6ffea30848179ef8641d5f34 (diff)
downloadmongo-e399b6676c5fc11df61e9b8ca4c27a2f7fc1e584.tar.gz
SERVER-64467 Refactor TicketHolders to not use global context
-rw-r--r--src/mongo/db/catalog/collection_catalog_bm.cpp2
-rw-r--r--src/mongo/db/catalog_raii_test.cpp2
-rw-r--r--src/mongo/db/concurrency/d_concurrency_bm.cpp9
-rw-r--r--src/mongo/db/concurrency/d_concurrency_test.cpp74
-rw-r--r--src/mongo/db/concurrency/lock_manager_test.cpp208
-rw-r--r--src/mongo/db/concurrency/lock_manager_test_help.h3
-rw-r--r--src/mongo/db/concurrency/lock_state.cpp13
-rw-r--r--src/mongo/db/concurrency/lock_state.h7
-rw-r--r--src/mongo/db/concurrency/lock_state_test.cpp89
-rw-r--r--src/mongo/db/concurrency/lock_stats_test.cpp4
-rw-r--r--src/mongo/db/db_raii_multi_collection_test.cpp2
-rw-r--r--src/mongo/db/db_raii_test.cpp2
-rw-r--r--src/mongo/db/exec/sbe/abt/sbe_abt_diff_test.cpp2
-rw-r--r--src/mongo/db/mongod_main.cpp2
-rw-r--r--src/mongo/db/pipeline/process_interface/shardsvr_process_interface_test.cpp2
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_test.cpp3
-rw-r--r--src/mongo/db/service_entry_point_mongod.cpp2
-rw-r--r--src/mongo/db/storage/storage_engine_init.cpp26
-rw-r--r--src/mongo/db/storage/ticketholders.cpp39
-rw-r--r--src/mongo/db/storage/ticketholders.h7
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp5
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_server_status.cpp2
-rw-r--r--src/mongo/db/transaction_participant.cpp2
24 files changed, 265 insertions, 244 deletions
diff --git a/src/mongo/db/catalog/collection_catalog_bm.cpp b/src/mongo/db/catalog/collection_catalog_bm.cpp
index eedb6bf1e1c..3ff0e3375bd 100644
--- a/src/mongo/db/catalog/collection_catalog_bm.cpp
+++ b/src/mongo/db/catalog/collection_catalog_bm.cpp
@@ -51,7 +51,7 @@ public:
void onDestroyClient(Client* client) final {}
void onCreateOperationContext(OperationContext* opCtx) override {
- opCtx->setLockState(std::make_unique<LockerImpl>());
+ opCtx->setLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
}
void onDestroyOperationContext(OperationContext* opCtx) final {}
diff --git a/src/mongo/db/catalog_raii_test.cpp b/src/mongo/db/catalog_raii_test.cpp
index 2e615b22061..8e849db9c7e 100644
--- a/src/mongo/db/catalog_raii_test.cpp
+++ b/src/mongo/db/catalog_raii_test.cpp
@@ -57,7 +57,7 @@ public:
ClientAndCtx makeClientWithLocker(const std::string& clientName) {
auto client = getServiceContext()->makeClient(clientName);
auto opCtx = client->makeOperationContext();
- client->swapLockState(std::make_unique<LockerImpl>());
+ client->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
return std::make_pair(std::move(client), std::move(opCtx));
}
diff --git a/src/mongo/db/concurrency/d_concurrency_bm.cpp b/src/mongo/db/concurrency/d_concurrency_bm.cpp
index dd9b3223081..d59755db9db 100644
--- a/src/mongo/db/concurrency/d_concurrency_bm.cpp
+++ b/src/mongo/db/concurrency/d_concurrency_bm.cpp
@@ -58,7 +58,7 @@ public:
void onDestroyClient(Client* client) final {}
void onCreateOperationContext(OperationContext* opCtx) override {
- opCtx->setLockState(std::make_unique<LockerImpl>());
+ opCtx->setLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
}
void onDestroyOperationContext(OperationContext* opCtx) final {}
@@ -83,6 +83,7 @@ public:
auto client = getGlobalServiceContext()->makeClient(str::stream()
<< "test client for thread " << i);
auto opCtx = client->makeOperationContext();
+ locker[i] = std::make_unique<LockerImpl>(opCtx->getServiceContext());
clients.emplace_back(std::move(client), std::move(opCtx));
}
}
@@ -90,7 +91,7 @@ public:
protected:
std::vector<std::pair<ServiceContext::UniqueClient, ServiceContext::UniqueOperationContext>>
clients;
- std::array<LockerImpl, kMaxPerfThreads> locker;
+ std::array<std::unique_ptr<LockerImpl>, kMaxPerfThreads> locker;
};
BENCHMARK_DEFINE_F(DConcurrencyTest, BM_StdMutex)(benchmark::State& state) {
@@ -105,7 +106,7 @@ BENCHMARK_DEFINE_F(DConcurrencyTest, BM_ResourceMutexShared)(benchmark::State& s
static Lock::ResourceMutex mtx("testMutex");
for (auto keepRunning : state) {
- Lock::SharedLock lk(&locker[state.thread_index], mtx);
+ Lock::SharedLock lk(locker[state.thread_index].get(), mtx);
}
}
@@ -113,7 +114,7 @@ BENCHMARK_DEFINE_F(DConcurrencyTest, BM_ResourceMutexExclusive)(benchmark::State
static Lock::ResourceMutex mtx("testMutex");
for (auto keepRunning : state) {
- Lock::ExclusiveLock lk(&locker[state.thread_index], mtx);
+ Lock::ExclusiveLock lk(locker[state.thread_index].get(), mtx);
}
}
diff --git a/src/mongo/db/concurrency/d_concurrency_test.cpp b/src/mongo/db/concurrency/d_concurrency_test.cpp
index b4b0f801efa..233d1dd1842 100644
--- a/src/mongo/db/concurrency/d_concurrency_test.cpp
+++ b/src/mongo/db/concurrency/d_concurrency_test.cpp
@@ -71,15 +71,18 @@ const auto kMaxClockJitterMillis = Milliseconds(0);
class UseGlobalThrottling {
public:
explicit UseGlobalThrottling(OperationContext* opCtx, int numTickets) {
- auto& ticketHolders = ticketHoldersDecoration(getGlobalServiceContext());
+ auto& ticketHolders = TicketHolders::get(opCtx->getServiceContext());
ticketHolders.setGlobalThrottling(
std::make_unique<SemaphoreTicketHolder>(numTickets, nullptr),
std::make_unique<SemaphoreTicketHolder>(numTickets, nullptr));
+ _ticketHolders = &ticketHolders;
}
~UseGlobalThrottling() noexcept(false) {
- auto& ticketHolders = ticketHoldersDecoration(getGlobalServiceContext());
- ticketHolders.setGlobalThrottling(nullptr, nullptr);
+ _ticketHolders->setGlobalThrottling(nullptr, nullptr);
}
+
+private:
+ TicketHolders* _ticketHolders;
};
@@ -98,7 +101,7 @@ public:
auto client =
getServiceContext()->makeClient(str::stream() << "test client for thread " << i);
auto opCtx = client->makeOperationContext();
- client->swapLockState(std::make_unique<LockerImpl>());
+ client->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
clients.emplace_back(std::move(client), std::move(opCtx));
}
return clients;
@@ -134,13 +137,13 @@ public:
TEST_F(DConcurrencyTestFixture, WriteConflictRetryInstantiatesOK) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
writeConflictRetry(opCtx.get(), "", "", [] {});
}
TEST_F(DConcurrencyTestFixture, WriteConflictRetryRetriesFunctionOnWriteConflictException) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
auto&& opDebug = CurOp::get(opCtx.get())->debug();
ASSERT_EQUALS(0, opDebug.additiveMetrics.writeConflicts.load());
ASSERT_EQUALS(100, writeConflictRetry(opCtx.get(), "", "", [&opDebug] {
@@ -154,7 +157,7 @@ TEST_F(DConcurrencyTestFixture, WriteConflictRetryRetriesFunctionOnWriteConflict
TEST_F(DConcurrencyTestFixture, WriteConflictRetryPropagatesNonWriteConflictException) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
ASSERT_THROWS_CODE(writeConflictRetry(opCtx.get(),
"",
"",
@@ -169,7 +172,7 @@ TEST_F(DConcurrencyTestFixture, WriteConflictRetryPropagatesNonWriteConflictExce
TEST_F(DConcurrencyTestFixture,
WriteConflictRetryPropagatesWriteConflictExceptionIfAlreadyInAWriteUnitOfWork) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
Lock::GlobalWrite globalWrite(opCtx.get());
WriteUnitOfWork wuow(opCtx.get());
ASSERT_THROWS(writeConflictRetry(opCtx.get(), "", "", [] { throw WriteConflictException(); }),
@@ -178,9 +181,10 @@ TEST_F(DConcurrencyTestFixture,
TEST_F(DConcurrencyTestFixture, ResourceMutex) {
Lock::ResourceMutex mtx("testMutex");
- LockerImpl locker1;
- LockerImpl locker2;
- LockerImpl locker3;
+ auto opCtx = makeOperationContext();
+ LockerImpl locker1(opCtx->getServiceContext());
+ LockerImpl locker2(opCtx->getServiceContext());
+ LockerImpl locker3(opCtx->getServiceContext());
struct State {
void check(int n) {
@@ -257,7 +261,7 @@ TEST_F(DConcurrencyTestFixture, ResourceMutex) {
TEST_F(DConcurrencyTestFixture, GlobalRead) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
Lock::GlobalRead globalRead(opCtx.get());
ASSERT(opCtx->lockState()->isR());
ASSERT_EQ(opCtx->lockState()->getLockMode(resourceIdReplicationStateTransitionLock), MODE_IX);
@@ -265,7 +269,7 @@ TEST_F(DConcurrencyTestFixture, GlobalRead) {
TEST_F(DConcurrencyTestFixture, GlobalWrite) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
Lock::GlobalWrite globalWrite(opCtx.get());
ASSERT(opCtx->lockState()->isW());
ASSERT_EQ(opCtx->lockState()->getLockMode(resourceIdReplicationStateTransitionLock), MODE_IX);
@@ -273,7 +277,7 @@ TEST_F(DConcurrencyTestFixture, GlobalWrite) {
TEST_F(DConcurrencyTestFixture, GlobalWriteAndGlobalRead) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
auto lockState = opCtx->lockState();
Lock::GlobalWrite globalWrite(opCtx.get());
@@ -291,7 +295,7 @@ TEST_F(DConcurrencyTestFixture, GlobalWriteAndGlobalRead) {
TEST_F(DConcurrencyTestFixture,
GlobalWriteRequiresExplicitDowngradeToIntentWriteModeIfDestroyedWhileHoldingDatabaseLock) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
auto lockState = opCtx->lockState();
auto globalWrite = std::make_unique<Lock::GlobalWrite>(opCtx.get());
@@ -333,7 +337,7 @@ TEST_F(DConcurrencyTestFixture,
TEST_F(DConcurrencyTestFixture,
GlobalWriteRequiresSupportsDowngradeToIntentWriteModeWhileHoldingDatabaseLock) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
auto lockState = opCtx->lockState();
auto globalWrite = std::make_unique<Lock::GlobalWrite>(opCtx.get());
@@ -374,7 +378,7 @@ TEST_F(DConcurrencyTestFixture,
TEST_F(DConcurrencyTestFixture,
NestedGlobalWriteSupportsDowngradeToIntentWriteModeWhileHoldingDatabaseLock) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
auto lockState = opCtx->lockState();
auto outerGlobalWrite = std::make_unique<Lock::GlobalWrite>(opCtx.get());
@@ -1066,7 +1070,7 @@ TEST_F(DConcurrencyTestFixture, LockCompleteInterruptedWhenUncontested) {
TEST_F(DConcurrencyTestFixture, DBLockTakesS) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
Lock::DBLock dbRead(opCtx.get(), "db", MODE_S);
const ResourceId resIdDb(RESOURCE_DATABASE, std::string("db"));
@@ -1075,7 +1079,7 @@ TEST_F(DConcurrencyTestFixture, DBLockTakesS) {
TEST_F(DConcurrencyTestFixture, DBLockTakesX) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
Lock::DBLock dbWrite(opCtx.get(), "db", MODE_X);
const ResourceId resIdDb(RESOURCE_DATABASE, std::string("db"));
@@ -1084,7 +1088,7 @@ TEST_F(DConcurrencyTestFixture, DBLockTakesX) {
TEST_F(DConcurrencyTestFixture, DBLockTakesISForAdminIS) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
Lock::DBLock dbRead(opCtx.get(), "admin", MODE_IS);
ASSERT(opCtx->lockState()->getLockMode(resourceIdAdminDB) == MODE_IS);
@@ -1092,7 +1096,7 @@ TEST_F(DConcurrencyTestFixture, DBLockTakesISForAdminIS) {
TEST_F(DConcurrencyTestFixture, DBLockTakesSForAdminS) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
Lock::DBLock dbRead(opCtx.get(), "admin", MODE_S);
ASSERT(opCtx->lockState()->getLockMode(resourceIdAdminDB) == MODE_S);
@@ -1100,7 +1104,7 @@ TEST_F(DConcurrencyTestFixture, DBLockTakesSForAdminS) {
TEST_F(DConcurrencyTestFixture, DBLockTakesIXForAdminIX) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
Lock::DBLock dbWrite(opCtx.get(), "admin", MODE_IX);
ASSERT(opCtx->lockState()->getLockMode(resourceIdAdminDB) == MODE_IX);
@@ -1108,7 +1112,7 @@ TEST_F(DConcurrencyTestFixture, DBLockTakesIXForAdminIX) {
TEST_F(DConcurrencyTestFixture, DBLockTakesXForAdminX) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
Lock::DBLock dbWrite(opCtx.get(), "admin", MODE_X);
ASSERT(opCtx->lockState()->getLockMode(resourceIdAdminDB) == MODE_X);
@@ -1116,7 +1120,7 @@ TEST_F(DConcurrencyTestFixture, DBLockTakesXForAdminX) {
TEST_F(DConcurrencyTestFixture, MultipleWriteDBLocksOnSameThread) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
Lock::DBLock r1(opCtx.get(), "db1", MODE_X);
Lock::DBLock r2(opCtx.get(), "db1", MODE_X);
@@ -1125,7 +1129,7 @@ TEST_F(DConcurrencyTestFixture, MultipleWriteDBLocksOnSameThread) {
TEST_F(DConcurrencyTestFixture, MultipleConflictingDBLocksOnSameThread) {
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
auto lockState = opCtx->lockState();
Lock::DBLock r1(opCtx.get(), "db1", MODE_X);
Lock::DBLock r2(opCtx.get(), "db1", MODE_S);
@@ -1138,7 +1142,7 @@ TEST_F(DConcurrencyTestFixture, IsDbLockedForSMode) {
const std::string dbName("db");
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
auto lockState = opCtx->lockState();
Lock::DBLock dbLock(opCtx.get(), dbName, MODE_S);
@@ -1152,7 +1156,7 @@ TEST_F(DConcurrencyTestFixture, IsDbLockedForXMode) {
const std::string dbName("db");
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
auto lockState = opCtx->lockState();
Lock::DBLock dbLock(opCtx.get(), dbName, MODE_X);
@@ -1166,7 +1170,7 @@ TEST_F(DConcurrencyTestFixture, IsCollectionLocked_DB_Locked_IS) {
const NamespaceString ns("db1.coll");
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
auto lockState = opCtx->lockState();
Lock::DBLock dbLock(opCtx.get(), "db1", MODE_IS);
@@ -1194,7 +1198,7 @@ TEST_F(DConcurrencyTestFixture, IsCollectionLocked_DB_Locked_IX) {
const NamespaceString ns("db1.coll");
auto opCtx = makeOperationContext();
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
auto lockState = opCtx->lockState();
Lock::DBLock dbLock(opCtx.get(), "db1", MODE_IX);
@@ -2188,9 +2192,9 @@ TEST_F(DConcurrencyTestFixture, FailPointInLockDoesNotFailUninterruptibleGlobalN
FailPointEnableBlock failWaitingNonPartitionedLocks("failNonIntentLocksIfWaitNeeded");
- LockerImpl locker1;
- LockerImpl locker2;
- LockerImpl locker3;
+ LockerImpl locker1(opCtx->getServiceContext());
+ LockerImpl locker2(opCtx->getServiceContext());
+ LockerImpl locker3(opCtx->getServiceContext());
{
locker1.lockGlobal(opCtx.get(), MODE_IX);
@@ -2232,9 +2236,9 @@ TEST_F(DConcurrencyTestFixture, FailPointInLockDoesNotFailUninterruptibleNonInte
FailPointEnableBlock failWaitingNonPartitionedLocks("failNonIntentLocksIfWaitNeeded");
- LockerImpl locker1;
- LockerImpl locker2;
- LockerImpl locker3;
+ LockerImpl locker1(opCtx->getServiceContext());
+ LockerImpl locker2(opCtx->getServiceContext());
+ LockerImpl locker3(opCtx->getServiceContext());
// Granted MODE_X lock, fail incoming MODE_S and MODE_X.
const ResourceId resId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
diff --git a/src/mongo/db/concurrency/lock_manager_test.cpp b/src/mongo/db/concurrency/lock_manager_test.cpp
index 73787f72c1e..ffc72d559b1 100644
--- a/src/mongo/db/concurrency/lock_manager_test.cpp
+++ b/src/mongo/db/concurrency/lock_manager_test.cpp
@@ -29,10 +29,13 @@
#include "mongo/db/concurrency/lock_manager_defs.h"
#include "mongo/db/concurrency/lock_manager_test_help.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
+class LockManagerTest : public ServiceContextTest {};
+
TEST(ResourceId, Semantics) {
ResourceId resIdDb(RESOURCE_DATABASE, 324334234);
ASSERT(resIdDb.getType() == RESOURCE_DATABASE);
@@ -81,11 +84,11 @@ TEST(ResourceId, Masking) {
// LockManager
//
-TEST(LockManager, Grant) {
+TEST_F(LockManagerTest, Grant) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker;
+ LockerImpl locker(getServiceContext());
TrackingLockGrantNotification notify;
LockRequest request;
@@ -100,11 +103,11 @@ TEST(LockManager, Grant) {
ASSERT(request.recursiveCount == 0);
}
-TEST(LockManager, GrantMultipleNoConflict) {
+TEST_F(LockManagerTest, GrantMultipleNoConflict) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker;
+ LockerImpl locker(getServiceContext());
TrackingLockGrantNotification notify;
LockRequest request[6];
@@ -133,13 +136,13 @@ TEST(LockManager, GrantMultipleNoConflict) {
lockMgr.unlock(&request[4]);
}
-TEST(LockManager, GrantMultipleFIFOOrder) {
+TEST_F(LockManagerTest, GrantMultipleFIFOOrder) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
std::unique_ptr<LockerImpl> locker[6];
for (int i = 0; i < 6; i++) {
- locker[i].reset(new LockerImpl());
+ locker[i].reset(new LockerImpl(getServiceContext()));
}
TrackingLockGrantNotification notify[6];
@@ -166,11 +169,11 @@ TEST(LockManager, GrantMultipleFIFOOrder) {
lockMgr.unlock(&request[5]);
}
-TEST(LockManager, GrantRecursive) {
+TEST_F(LockManagerTest, GrantRecursive) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker;
+ LockerImpl locker(getServiceContext());
LockRequestCombo request(&locker);
ASSERT(LOCK_OK == lockMgr.lock(resId, &request, MODE_S));
@@ -194,11 +197,11 @@ TEST(LockManager, GrantRecursive) {
ASSERT(request.recursiveCount == 0);
}
-TEST(LockManager, GrantRecursiveCompatibleConvertUp) {
+TEST_F(LockManagerTest, GrantRecursiveCompatibleConvertUp) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker;
+ LockerImpl locker(getServiceContext());
LockRequestCombo request(&locker);
ASSERT(LOCK_OK == lockMgr.lock(resId, &request, MODE_IS));
@@ -222,11 +225,11 @@ TEST(LockManager, GrantRecursiveCompatibleConvertUp) {
ASSERT(request.recursiveCount == 0);
}
-TEST(LockManager, GrantRecursiveNonCompatibleConvertUp) {
+TEST_F(LockManagerTest, GrantRecursiveNonCompatibleConvertUp) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker;
+ LockerImpl locker(getServiceContext());
LockRequestCombo request(&locker);
ASSERT(LOCK_OK == lockMgr.lock(resId, &request, MODE_S));
@@ -250,11 +253,11 @@ TEST(LockManager, GrantRecursiveNonCompatibleConvertUp) {
ASSERT(request.recursiveCount == 0);
}
-TEST(LockManager, GrantRecursiveNonCompatibleConvertDown) {
+TEST_F(LockManagerTest, GrantRecursiveNonCompatibleConvertDown) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker;
+ LockerImpl locker(getServiceContext());
LockRequestCombo request(&locker);
ASSERT(LOCK_OK == lockMgr.lock(resId, &request, MODE_X));
@@ -278,12 +281,12 @@ TEST(LockManager, GrantRecursiveNonCompatibleConvertDown) {
ASSERT(request.recursiveCount == 0);
}
-TEST(LockManager, Conflict) {
+TEST_F(LockManagerTest, Conflict) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker1;
- LockerImpl locker2;
+ LockerImpl locker1(getServiceContext());
+ LockerImpl locker2(getServiceContext());
LockRequestCombo request1(&locker1);
LockRequestCombo request2(&locker2);
@@ -317,11 +320,11 @@ TEST(LockManager, Conflict) {
ASSERT(request2.numNotifies == 1);
}
-TEST(LockManager, MultipleConflict) {
+TEST_F(LockManagerTest, MultipleConflict) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker;
+ LockerImpl locker(getServiceContext());
TrackingLockGrantNotification notify;
LockRequest request[6];
@@ -350,14 +353,14 @@ TEST(LockManager, MultipleConflict) {
}
}
-TEST(LockManager, ConflictCancelWaiting) {
+TEST_F(LockManagerTest, ConflictCancelWaiting) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker1;
+ LockerImpl locker1(getServiceContext());
TrackingLockGrantNotification notify1;
- LockerImpl locker2;
+ LockerImpl locker2(getServiceContext());
TrackingLockGrantNotification notify2;
LockRequest request1;
@@ -383,11 +386,11 @@ TEST(LockManager, ConflictCancelWaiting) {
lockMgr.unlock(&request1);
}
-TEST(LockManager, ConflictCancelMultipleWaiting) {
+TEST_F(LockManagerTest, ConflictCancelMultipleWaiting) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker;
+ LockerImpl locker(getServiceContext());
TrackingLockGrantNotification notify;
LockRequest request[6];
@@ -416,12 +419,12 @@ TEST(LockManager, ConflictCancelMultipleWaiting) {
lockMgr.unlock(&request[0]);
}
-TEST(LockManager, CancelWaitingConversionWeakModes) {
+TEST_F(LockManagerTest, CancelWaitingConversionWeakModes) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker1;
- LockerImpl locker2;
+ LockerImpl locker1(getServiceContext());
+ LockerImpl locker2(getServiceContext());
LockRequestCombo request1(&locker1);
LockRequestCombo request2(&locker2);
@@ -451,12 +454,12 @@ TEST(LockManager, CancelWaitingConversionWeakModes) {
lockMgr.unlock(&request2);
}
-TEST(LockManager, CancelWaitingConversionStrongModes) {
+TEST_F(LockManagerTest, CancelWaitingConversionStrongModes) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker1;
- LockerImpl locker2;
+ LockerImpl locker1(getServiceContext());
+ LockerImpl locker2(getServiceContext());
LockRequestCombo request1(&locker1);
LockRequestCombo request2(&locker2);
@@ -486,12 +489,12 @@ TEST(LockManager, CancelWaitingConversionStrongModes) {
lockMgr.unlock(&request2);
}
-TEST(LockManager, ConflictingConversion) {
+TEST_F(LockManagerTest, ConflictingConversion) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker1;
- LockerImpl locker2;
+ LockerImpl locker1(getServiceContext());
+ LockerImpl locker2(getServiceContext());
LockRequestCombo request1(&locker1);
LockRequestCombo request2(&locker2);
@@ -521,11 +524,11 @@ TEST(LockManager, ConflictingConversion) {
lockMgr.unlock(&request1);
}
-TEST(LockManager, ConflictingConversionInTheMiddle) {
+TEST_F(LockManagerTest, ConflictingConversionInTheMiddle) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker;
+ LockerImpl locker(getServiceContext());
TrackingLockGrantNotification notify;
LockRequest request[3];
@@ -553,15 +556,15 @@ TEST(LockManager, ConflictingConversionInTheMiddle) {
lockMgr.unlock(&request[1]);
}
-TEST(LockManager, ConvertUpgrade) {
+TEST_F(LockManagerTest, ConvertUpgrade) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker1;
+ LockerImpl locker1(getServiceContext());
LockRequestCombo request1(&locker1);
ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_S));
- LockerImpl locker2;
+ LockerImpl locker2(getServiceContext());
LockRequestCombo request2(&locker2);
ASSERT(LOCK_OK == lockMgr.lock(resId, &request2, MODE_S));
@@ -574,15 +577,15 @@ TEST(LockManager, ConvertUpgrade) {
ASSERT(lockMgr.unlock(&request2));
}
-TEST(LockManager, Downgrade) {
+TEST_F(LockManagerTest, Downgrade) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl locker1;
+ LockerImpl locker1(getServiceContext());
LockRequestCombo request1(&locker1);
ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_X));
- LockerImpl locker2;
+ LockerImpl locker2(getServiceContext());
LockRequestCombo request2(&locker2);
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request2, MODE_S));
@@ -599,18 +602,21 @@ TEST(LockManager, Downgrade) {
// Lock conflict matrix tests
-static void checkConflict(LockMode existingMode, LockMode newMode, bool hasConflict) {
+static void checkConflict(ServiceContext* serviceContext,
+ LockMode existingMode,
+ LockMode newMode,
+ bool hasConflict) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl lockerExisting;
+ LockerImpl lockerExisting(serviceContext);
TrackingLockGrantNotification notifyExisting;
LockRequest requestExisting;
requestExisting.initNew(&lockerExisting, &notifyExisting);
ASSERT(LOCK_OK == lockMgr.lock(resId, &requestExisting, existingMode));
- LockerImpl lockerNew;
+ LockerImpl lockerNew(serviceContext);
TrackingLockGrantNotification notifyNew;
LockRequest requestNew;
requestNew.initNew(&lockerNew, &notifyNew);
@@ -626,45 +632,45 @@ static void checkConflict(LockMode existingMode, LockMode newMode, bool hasConfl
lockMgr.unlock(&requestExisting);
}
-TEST(LockManager, ValidateConflictMatrix) {
- checkConflict(MODE_IS, MODE_IS, false);
- checkConflict(MODE_IS, MODE_IX, false);
- checkConflict(MODE_IS, MODE_S, false);
- checkConflict(MODE_IS, MODE_X, true);
-
- checkConflict(MODE_IX, MODE_IS, false);
- checkConflict(MODE_IX, MODE_IX, false);
- checkConflict(MODE_IX, MODE_S, true);
- checkConflict(MODE_IX, MODE_X, true);
-
- checkConflict(MODE_S, MODE_IS, false);
- checkConflict(MODE_S, MODE_IX, true);
- checkConflict(MODE_S, MODE_S, false);
- checkConflict(MODE_S, MODE_X, true);
-
- checkConflict(MODE_X, MODE_IS, true);
- checkConflict(MODE_X, MODE_IX, true);
- checkConflict(MODE_X, MODE_S, true);
- checkConflict(MODE_X, MODE_X, true);
+TEST_F(LockManagerTest, ValidateConflictMatrix) {
+ checkConflict(getServiceContext(), MODE_IS, MODE_IS, false);
+ checkConflict(getServiceContext(), MODE_IS, MODE_IX, false);
+ checkConflict(getServiceContext(), MODE_IS, MODE_S, false);
+ checkConflict(getServiceContext(), MODE_IS, MODE_X, true);
+
+ checkConflict(getServiceContext(), MODE_IX, MODE_IS, false);
+ checkConflict(getServiceContext(), MODE_IX, MODE_IX, false);
+ checkConflict(getServiceContext(), MODE_IX, MODE_S, true);
+ checkConflict(getServiceContext(), MODE_IX, MODE_X, true);
+
+ checkConflict(getServiceContext(), MODE_S, MODE_IS, false);
+ checkConflict(getServiceContext(), MODE_S, MODE_IX, true);
+ checkConflict(getServiceContext(), MODE_S, MODE_S, false);
+ checkConflict(getServiceContext(), MODE_S, MODE_X, true);
+
+ checkConflict(getServiceContext(), MODE_X, MODE_IS, true);
+ checkConflict(getServiceContext(), MODE_X, MODE_IX, true);
+ checkConflict(getServiceContext(), MODE_X, MODE_S, true);
+ checkConflict(getServiceContext(), MODE_X, MODE_X, true);
}
-TEST(LockManager, EnqueueAtFront) {
+TEST_F(LockManagerTest, EnqueueAtFront) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));
- LockerImpl lockerX;
+ LockerImpl lockerX(getServiceContext());
LockRequestCombo requestX(&lockerX);
ASSERT(LOCK_OK == lockMgr.lock(resId, &requestX, MODE_X));
// The subsequent request will block
- LockerImpl lockerLow;
+ LockerImpl lockerLow(getServiceContext());
LockRequestCombo requestLow(&lockerLow);
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestLow, MODE_X));
// This is a "queue jumping request", which will go before locker 2 above
- LockerImpl lockerHi;
+ LockerImpl lockerHi(getServiceContext());
LockRequestCombo requestHi(&lockerHi);
requestHi.enqueueAtFront = true;
@@ -686,18 +692,18 @@ TEST(LockManager, EnqueueAtFront) {
ASSERT(lockMgr.unlock(&requestLow));
}
-TEST(LockManager, CompatibleFirstImmediateGrant) {
+TEST_F(LockManagerTest, CompatibleFirstImmediateGrant) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_GLOBAL, 0);
- LockerImpl locker1;
+ LockerImpl locker1(getServiceContext());
LockRequestCombo request1(&locker1);
- LockerImpl locker2;
+ LockerImpl locker2(getServiceContext());
LockRequestCombo request2(&locker2);
request2.compatibleFirst = true;
- LockerImpl locker3;
+ LockerImpl locker3(getServiceContext());
LockRequestCombo request3(&locker3);
// Lock all in IS mode
@@ -706,14 +712,14 @@ TEST(LockManager, CompatibleFirstImmediateGrant) {
ASSERT(LOCK_OK == lockMgr.lock(resId, &request3, MODE_IS));
// Now an exclusive mode comes, which would block
- LockerImpl lockerX;
+ LockerImpl lockerX(getServiceContext());
LockRequestCombo requestX(&lockerX);
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestX, MODE_X));
// If an S comes, it should be granted, because of request2
{
- LockerImpl lockerS;
+ LockerImpl lockerS(getServiceContext());
LockRequestCombo requestS(&lockerS);
ASSERT(LOCK_OK == lockMgr.lock(resId, &requestS, MODE_S));
ASSERT(lockMgr.unlock(&requestS));
@@ -724,7 +730,7 @@ TEST(LockManager, CompatibleFirstImmediateGrant) {
// If S comes again, it should be granted, because of request2 still there
{
- LockerImpl lockerS;
+ LockerImpl lockerS(getServiceContext());
LockRequestCombo requestS(&lockerS);
ASSERT(LOCK_OK == lockMgr.lock(resId, &requestS, MODE_S));
ASSERT(lockMgr.unlock(&requestS));
@@ -734,7 +740,7 @@ TEST(LockManager, CompatibleFirstImmediateGrant) {
ASSERT(lockMgr.unlock(&request2));
{
- LockerImpl lockerS;
+ LockerImpl lockerS(getServiceContext());
LockRequestCombo requestS(&lockerS);
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestS, MODE_S));
ASSERT(lockMgr.unlock(&requestS));
@@ -745,7 +751,7 @@ TEST(LockManager, CompatibleFirstImmediateGrant) {
ASSERT(lockMgr.unlock(&requestX));
}
-TEST(LockManager, CompatibleFirstGrantAlreadyQueued) {
+TEST_F(LockManagerTest, CompatibleFirstGrantAlreadyQueued) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_GLOBAL, 0);
@@ -760,17 +766,17 @@ TEST(LockManager, CompatibleFirstGrantAlreadyQueued) {
for (LockMode writerMode : conflictingModes) {
for (UnblockMethod unblockMethod : unblockMethods) {
- LockerImpl locker1;
+ LockerImpl locker1(getServiceContext());
LockRequestCombo request1(&locker1);
- LockerImpl locker2;
+ LockerImpl locker2(getServiceContext());
LockRequestCombo request2(&locker2);
request2.compatibleFirst = true;
- LockerImpl locker3;
+ LockerImpl locker3(getServiceContext());
LockRequestCombo request3(&locker3);
- LockerImpl locker4;
+ LockerImpl locker4(getServiceContext());
LockRequestCombo request4(&locker4);
// Hold the lock in X and establish the S IX|X IS queue.
@@ -805,22 +811,22 @@ TEST(LockManager, CompatibleFirstGrantAlreadyQueued) {
}
}
-TEST(LockManager, CompatibleFirstDelayedGrant) {
+TEST_F(LockManagerTest, CompatibleFirstDelayedGrant) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_GLOBAL, 0);
- LockerImpl lockerXInitial;
+ LockerImpl lockerXInitial(getServiceContext());
LockRequestCombo requestXInitial(&lockerXInitial);
ASSERT(LOCK_OK == lockMgr.lock(resId, &requestXInitial, MODE_X));
- LockerImpl locker1;
+ LockerImpl locker1(getServiceContext());
LockRequestCombo request1(&locker1);
- LockerImpl locker2;
+ LockerImpl locker2(getServiceContext());
LockRequestCombo request2(&locker2);
request2.compatibleFirst = true;
- LockerImpl locker3;
+ LockerImpl locker3(getServiceContext());
LockRequestCombo request3(&locker3);
// Lock all in IS mode (should block behind the global lock)
@@ -829,7 +835,7 @@ TEST(LockManager, CompatibleFirstDelayedGrant) {
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request3, MODE_IS));
// Now an exclusive mode comes, which would block behind the IS modes
- LockerImpl lockerX;
+ LockerImpl lockerX(getServiceContext());
LockRequestCombo requestX(&lockerX);
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestX, MODE_X));
@@ -841,7 +847,7 @@ TEST(LockManager, CompatibleFirstDelayedGrant) {
// If an S comes, it should be granted, because of request2
{
- LockerImpl lockerS;
+ LockerImpl lockerS(getServiceContext());
LockRequestCombo requestS(&lockerS);
ASSERT(LOCK_OK == lockMgr.lock(resId, &requestS, MODE_S));
ASSERT(lockMgr.unlock(&requestS));
@@ -852,7 +858,7 @@ TEST(LockManager, CompatibleFirstDelayedGrant) {
// If S comes again, it should be granted, because of request2 still there
{
- LockerImpl lockerS;
+ LockerImpl lockerS(getServiceContext());
LockRequestCombo requestS(&lockerS);
ASSERT(LOCK_OK == lockMgr.lock(resId, &requestS, MODE_S));
ASSERT(lockMgr.unlock(&requestS));
@@ -862,7 +868,7 @@ TEST(LockManager, CompatibleFirstDelayedGrant) {
ASSERT(lockMgr.unlock(&request2));
{
- LockerImpl lockerS;
+ LockerImpl lockerS(getServiceContext());
LockRequestCombo requestS(&lockerS);
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestS, MODE_S));
ASSERT(lockMgr.unlock(&requestS));
@@ -873,26 +879,26 @@ TEST(LockManager, CompatibleFirstDelayedGrant) {
ASSERT(lockMgr.unlock(&requestX));
}
-TEST(LockManager, CompatibleFirstCancelWaiting) {
+TEST_F(LockManagerTest, CompatibleFirstCancelWaiting) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_GLOBAL, 0);
- LockerImpl lockerSInitial;
+ LockerImpl lockerSInitial(getServiceContext());
LockRequestCombo requestSInitial(&lockerSInitial);
ASSERT(LOCK_OK == lockMgr.lock(resId, &requestSInitial, MODE_S));
- LockerImpl lockerX;
+ LockerImpl lockerX(getServiceContext());
LockRequestCombo requestX(&lockerX);
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestX, MODE_X));
- LockerImpl lockerPending;
+ LockerImpl lockerPending(getServiceContext());
LockRequestCombo requestPending(&lockerPending);
requestPending.compatibleFirst = true;
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestPending, MODE_S));
// S1 is not granted yet, so the policy should still be FIFO
{
- LockerImpl lockerS;
+ LockerImpl lockerS(getServiceContext());
LockRequestCombo requestS(&lockerS);
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestS, MODE_S));
ASSERT(lockMgr.unlock(&requestS));
@@ -902,7 +908,7 @@ TEST(LockManager, CompatibleFirstCancelWaiting) {
ASSERT(lockMgr.unlock(&requestPending));
{
- LockerImpl lockerS;
+ LockerImpl lockerS(getServiceContext());
LockRequestCombo requestS(&lockerS);
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestS, MODE_S));
ASSERT(lockMgr.unlock(&requestS));
@@ -913,26 +919,26 @@ TEST(LockManager, CompatibleFirstCancelWaiting) {
ASSERT(lockMgr.unlock(&requestX));
}
-TEST(LockManager, Fairness) {
+TEST_F(LockManagerTest, Fairness) {
LockManager lockMgr;
const ResourceId resId(RESOURCE_GLOBAL, 0);
// Start with some 'regular' intent locks
- LockerImpl lockerIS;
+ LockerImpl lockerIS(getServiceContext());
LockRequestCombo requestIS(&lockerIS);
ASSERT(LOCK_OK == lockMgr.lock(resId, &requestIS, MODE_IS));
- LockerImpl lockerIX;
+ LockerImpl lockerIX(getServiceContext());
LockRequestCombo requestIX(&lockerIX);
ASSERT(LOCK_OK == lockMgr.lock(resId, &requestIX, MODE_IX));
// Now a conflicting lock comes
- LockerImpl lockerX;
+ LockerImpl lockerX(getServiceContext());
LockRequestCombo requestX(&lockerX);
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestX, MODE_X));
// Now, whoever comes next should be blocked
- LockerImpl lockerIX1;
+ LockerImpl lockerIX1(getServiceContext());
LockRequestCombo requestIX1(&lockerIX1);
ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestIX1, MODE_IX));
diff --git a/src/mongo/db/concurrency/lock_manager_test_help.h b/src/mongo/db/concurrency/lock_manager_test_help.h
index bfd0cd273b2..5eba9d33dbd 100644
--- a/src/mongo/db/concurrency/lock_manager_test_help.h
+++ b/src/mongo/db/concurrency/lock_manager_test_help.h
@@ -36,7 +36,8 @@ namespace mongo {
class LockerForTests : public LockerImpl {
public:
- explicit LockerForTests(OperationContext* opCtx, LockMode globalLockMode) {
+ explicit LockerForTests(OperationContext* opCtx, LockMode globalLockMode)
+ : LockerImpl(opCtx->getServiceContext()) {
lockGlobal(opCtx, globalLockMode);
}
diff --git a/src/mongo/db/concurrency/lock_state.cpp b/src/mongo/db/concurrency/lock_state.cpp
index e53c23a09f9..a968d2eee6e 100644
--- a/src/mongo/db/concurrency/lock_state.cpp
+++ b/src/mongo/db/concurrency/lock_state.cpp
@@ -291,8 +291,11 @@ void CondVarLockGrantNotification::notify(ResourceId resId, LockResult result) {
// Locker
//
-LockerImpl::LockerImpl()
- : _id(idCounter.addAndFetch(1)), _wuowNestingLevel(0), _threadId(stdx::this_thread::get_id()) {}
+LockerImpl::LockerImpl(ServiceContext* serviceCtx)
+ : _id(idCounter.addAndFetch(1)),
+ _wuowNestingLevel(0),
+ _threadId(stdx::this_thread::get_id()),
+ _ticketHolders(&TicketHolders::get(serviceCtx)) {}
stdx::thread::id LockerImpl::getThreadId() const {
return _threadId;
@@ -361,8 +364,7 @@ void LockerImpl::reacquireTicket(OperationContext* opCtx) {
bool LockerImpl::_acquireTicket(OperationContext* opCtx, LockMode mode, Date_t deadline) {
const bool reader = isSharedLockMode(mode);
- auto& ticketHolders = ticketHoldersDecoration(getGlobalServiceContext());
- auto holder = shouldAcquireTicket() ? ticketHolders.getTicketHolder(mode) : nullptr;
+ auto holder = shouldAcquireTicket() ? _ticketHolders->getTicketHolder(mode) : nullptr;
if (holder) {
_clientState.store(reader ? kQueuedReader : kQueuedWriter);
@@ -1074,8 +1076,7 @@ void LockerImpl::releaseTicket() {
}
void LockerImpl::_releaseTicket() {
- auto& ticketHolders = ticketHoldersDecoration(getGlobalServiceContext());
- auto holder = shouldAcquireTicket() ? ticketHolders.getTicketHolder(_modeForTicket) : nullptr;
+ auto holder = shouldAcquireTicket() ? _ticketHolders->getTicketHolder(_modeForTicket) : nullptr;
if (holder) {
holder->release(&_admCtx, std::move(*_ticket));
}
diff --git a/src/mongo/db/concurrency/lock_state.h b/src/mongo/db/concurrency/lock_state.h
index 31096da3cf8..a6677385e2f 100644
--- a/src/mongo/db/concurrency/lock_state.h
+++ b/src/mongo/db/concurrency/lock_state.h
@@ -35,6 +35,7 @@
#include "mongo/db/concurrency/lock_manager_defs.h"
#include "mongo/db/concurrency/locker.h"
#include "mongo/db/operation_context.h"
+#include "mongo/db/storage/ticketholders.h"
#include "mongo/platform/atomic_word.h"
#include "mongo/util/concurrency/admission_context.h"
#include "mongo/util/concurrency/spin_lock.h"
@@ -85,7 +86,6 @@ private:
LockResult _result;
};
-
/**
* Interface for acquiring locks. One of those objects will have to be instantiated for each
* request (transaction).
@@ -101,7 +101,7 @@ public:
* Instantiates new locker. Must be given a unique identifier for disambiguation. Lockers
* having the same identifier will not conflict on lock acquisition.
*/
- LockerImpl();
+ LockerImpl(ServiceContext* serviceContext);
virtual ~LockerImpl();
@@ -381,6 +381,9 @@ private:
// Keeps state and statistics related to admission control.
AdmissionContext _admCtx;
+ // The global ticketholders of the service context.
+ TicketHolders* _ticketHolders;
+
// This will only be valid when holding a ticket.
boost::optional<Ticket> _ticket;
diff --git a/src/mongo/db/concurrency/lock_state_test.cpp b/src/mongo/db/concurrency/lock_state_test.cpp
index 86aeb32e3f4..32d819899e1 100644
--- a/src/mongo/db/concurrency/lock_state_test.cpp
+++ b/src/mongo/db/concurrency/lock_state_test.cpp
@@ -55,7 +55,7 @@ TEST_F(LockerImplTest, LockNoConflict) {
const ResourceId resId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
locker.lockGlobal(opCtx.get(), MODE_IX);
locker.lock(resId, MODE_X);
@@ -75,7 +75,7 @@ TEST_F(LockerImplTest, ReLockNoConflict) {
const ResourceId resId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
locker.lockGlobal(opCtx.get(), MODE_IX);
locker.lock(resId, MODE_S);
@@ -95,11 +95,11 @@ TEST_F(LockerImplTest, ConflictWithTimeout) {
const ResourceId resId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
- LockerImpl locker1;
+ LockerImpl locker1(opCtx->getServiceContext());
locker1.lockGlobal(opCtx.get(), MODE_IX);
locker1.lock(resId, MODE_X);
- LockerImpl locker2;
+ LockerImpl locker2(opCtx->getServiceContext());
locker2.lockGlobal(opCtx.get(), MODE_IX);
ASSERT_THROWS_CODE(locker2.lock(opCtx.get(), resId, MODE_S, Date_t::now()),
@@ -119,11 +119,11 @@ TEST_F(LockerImplTest, ConflictUpgradeWithTimeout) {
const ResourceId resId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
- LockerImpl locker1;
+ LockerImpl locker1(opCtx->getServiceContext());
locker1.lockGlobal(opCtx.get(), MODE_IS);
locker1.lock(resId, MODE_S);
- LockerImpl locker2;
+ LockerImpl locker2(opCtx->getServiceContext());
locker2.lockGlobal(opCtx.get(), MODE_IS);
locker2.lock(resId, MODE_S);
@@ -144,19 +144,19 @@ TEST_F(LockerImplTest, FailPointInLockFailsGlobalNonIntentLocksIfTheyCannotBeImm
AlternativeClientRegion acr(newClient);
auto newOpCtx = cc().makeOperationContext();
- LockerImpl locker1;
+ LockerImpl locker1(newOpCtx->getServiceContext());
locker1.lockGlobal(newOpCtx.get(), MODE_IX);
{
FailPointEnableBlock failWaitingNonPartitionedLocks("failNonIntentLocksIfWaitNeeded");
// MODE_S attempt.
- LockerImpl locker2;
+ LockerImpl locker2(newOpCtx->getServiceContext());
ASSERT_THROWS_CODE(
locker2.lockGlobal(newOpCtx.get(), MODE_S), DBException, ErrorCodes::LockTimeout);
// MODE_X attempt.
- LockerImpl locker3;
+ LockerImpl locker3(newOpCtx->getServiceContext());
ASSERT_THROWS_CODE(
locker3.lockGlobal(newOpCtx.get(), MODE_X), DBException, ErrorCodes::LockTimeout);
}
@@ -175,7 +175,7 @@ TEST_F(LockerImplTest, FailPointInLockFailsNonIntentLocksIfTheyCannotBeImmediate
// Granted MODE_X lock, fail incoming MODE_S and MODE_X.
const ResourceId resId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
- LockerImpl locker1;
+ LockerImpl locker1(newOpCtx->getServiceContext());
locker1.lockGlobal(newOpCtx.get(), MODE_IX);
locker1.lock(newOpCtx.get(), resId, MODE_X);
@@ -183,7 +183,7 @@ TEST_F(LockerImplTest, FailPointInLockFailsNonIntentLocksIfTheyCannotBeImmediate
FailPointEnableBlock failWaitingNonPartitionedLocks("failNonIntentLocksIfWaitNeeded");
// MODE_S attempt.
- LockerImpl locker2;
+ LockerImpl locker2(newOpCtx->getServiceContext());
locker2.lockGlobal(newOpCtx.get(), MODE_IS);
ASSERT_THROWS_CODE(locker2.lock(newOpCtx.get(), resId, MODE_S, Date_t::max()),
DBException,
@@ -195,7 +195,7 @@ TEST_F(LockerImplTest, FailPointInLockFailsNonIntentLocksIfTheyCannotBeImmediate
locker2.unlockGlobal();
// MODE_X attempt.
- LockerImpl locker3;
+ LockerImpl locker3(newOpCtx->getServiceContext());
locker3.lockGlobal(newOpCtx.get(), MODE_IX);
ASSERT_THROWS_CODE(locker3.lock(newOpCtx.get(), resId, MODE_X, Date_t::max()),
DBException,
@@ -213,7 +213,7 @@ TEST_F(LockerImplTest, FailPointInLockFailsNonIntentLocksIfTheyCannotBeImmediate
TEST_F(LockerImplTest, ReadTransaction) {
auto opCtx = makeOperationContext();
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
locker.lockGlobal(opCtx.get(), MODE_IS);
locker.unlockGlobal();
@@ -235,7 +235,7 @@ TEST_F(LockerImplTest, saveAndRestoreGlobal) {
Locker::LockSnapshot lockInfo;
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
// No lock requests made, no locks held.
locker.saveLockStateAndUnlock(&lockInfo);
@@ -264,7 +264,7 @@ TEST_F(LockerImplTest, saveAndRestoreRSTL) {
Locker::LockSnapshot lockInfo;
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
const ResourceId resIdDatabase(RESOURCE_DATABASE, "TestDB"_sd);
@@ -303,7 +303,7 @@ TEST_F(LockerImplTest, saveAndRestoreGlobalAcquiredTwice) {
Locker::LockSnapshot lockInfo;
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
// No lock requests made, no locks held.
locker.saveLockStateAndUnlock(&lockInfo);
@@ -331,7 +331,7 @@ TEST_F(LockerImplTest, saveAndRestoreDBAndCollection) {
Locker::LockSnapshot lockInfo;
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
const ResourceId resIdDatabase(RESOURCE_DATABASE, "TestDB"_sd);
const ResourceId resIdCollection(RESOURCE_COLLECTION, "TestDB.collection"_sd);
@@ -361,7 +361,7 @@ TEST_F(LockerImplTest, releaseWriteUnitOfWork) {
Locker::LockSnapshot lockInfo;
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
const ResourceId resIdDatabase(RESOURCE_DATABASE, "TestDB"_sd);
const ResourceId resIdCollection(RESOURCE_COLLECTION, "TestDB.collection"_sd);
@@ -391,7 +391,7 @@ TEST_F(LockerImplTest, restoreWriteUnitOfWork) {
Locker::LockSnapshot lockInfo;
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
const ResourceId resIdDatabase(RESOURCE_DATABASE, "TestDB"_sd);
const ResourceId resIdCollection(RESOURCE_COLLECTION, "TestDB.collection"_sd);
@@ -433,7 +433,7 @@ TEST_F(LockerImplTest, releaseAndRestoreWriteUnitOfWorkWithoutUnlock) {
Locker::WUOWLockSnapshot lockInfo;
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
const ResourceId resIdDatabase(RESOURCE_DATABASE, "TestDB"_sd);
const ResourceId resIdCollection(RESOURCE_COLLECTION, "TestDB.collection"_sd);
@@ -549,7 +549,7 @@ TEST_F(LockerImplTest, releaseAndRestoreReadOnlyWriteUnitOfWork) {
Locker::LockSnapshot lockInfo;
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
const ResourceId resIdDatabase(RESOURCE_DATABASE, "TestDB"_sd);
const ResourceId resIdCollection(RESOURCE_COLLECTION, "TestDB.collection"_sd);
@@ -591,7 +591,8 @@ TEST_F(LockerImplTest, releaseAndRestoreReadOnlyWriteUnitOfWork) {
TEST_F(LockerImplTest, releaseAndRestoreEmptyWriteUnitOfWork) {
Locker::LockSnapshot lockInfo;
- LockerImpl locker;
+ auto opCtx = makeOperationContext();
+ LockerImpl locker(opCtx->getServiceContext());
// Snapshot transactions delay shared locks as well.
locker.setSharedLocksShouldTwoPhaseLock(true);
@@ -615,7 +616,7 @@ TEST_F(LockerImplTest, releaseAndRestoreWriteUnitOfWorkWithRecursiveLocks) {
Locker::LockSnapshot lockInfo;
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
const ResourceId resIdDatabase(RESOURCE_DATABASE, "TestDB"_sd);
const ResourceId resIdCollection(RESOURCE_COLLECTION, "TestDB.collection"_sd);
@@ -700,7 +701,7 @@ TEST_F(LockerImplTest, DefaultLocker) {
const ResourceId resId(RESOURCE_DATABASE, "TestDB"_sd);
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
locker.lockGlobal(opCtx.get(), MODE_IX);
locker.lock(resId, MODE_X);
@@ -727,7 +728,7 @@ TEST_F(LockerImplTest, SharedLocksShouldTwoPhaseLockIsTrue) {
const ResourceId resId3(RESOURCE_COLLECTION, "TestDB.collection3"_sd);
const ResourceId resId4(RESOURCE_COLLECTION, "TestDB.collection4"_sd);
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
locker.setSharedLocksShouldTwoPhaseLock(true);
locker.lockGlobal(opCtx.get(), MODE_IS);
@@ -783,7 +784,7 @@ TEST_F(LockerImplTest, ModeIXAndXLockParticipatesInTwoPhaseLocking) {
const ResourceId resId3(RESOURCE_COLLECTION, "TestDB.collection3"_sd);
const ResourceId resId4(RESOURCE_COLLECTION, "TestDB.collection4"_sd);
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
locker.lockGlobal(opCtx.get(), MODE_IX);
ASSERT_EQ(locker.getLockMode(resourceIdGlobal), MODE_IX);
@@ -826,7 +827,8 @@ TEST_F(LockerImplTest, ModeIXAndXLockParticipatesInTwoPhaseLocking) {
}
TEST_F(LockerImplTest, RSTLUnlocksWithNestedLock) {
- LockerImpl locker;
+ auto opCtx = makeOperationContext();
+ LockerImpl locker(opCtx->getServiceContext());
locker.lock(resourceIdReplicationStateTransitionLock, MODE_IX);
ASSERT_EQ(locker.getLockMode(resourceIdReplicationStateTransitionLock), MODE_IX);
@@ -851,7 +853,8 @@ TEST_F(LockerImplTest, RSTLUnlocksWithNestedLock) {
}
TEST_F(LockerImplTest, RSTLModeIXWithTwoPhaseLockingCanBeUnlockedWhenPrepared) {
- LockerImpl locker;
+ auto opCtx = makeOperationContext();
+ LockerImpl locker(opCtx->getServiceContext());
locker.lock(resourceIdReplicationStateTransitionLock, MODE_IX);
ASSERT_EQ(locker.getLockMode(resourceIdReplicationStateTransitionLock), MODE_IX);
@@ -875,7 +878,8 @@ TEST_F(LockerImplTest, RSTLModeIXWithTwoPhaseLockingCanBeUnlockedWhenPrepared) {
}
TEST_F(LockerImplTest, RSTLModeISWithTwoPhaseLockingCanBeUnlockedWhenPrepared) {
- LockerImpl locker;
+ auto opCtx = makeOperationContext();
+ LockerImpl locker(opCtx->getServiceContext());
locker.lock(resourceIdReplicationStateTransitionLock, MODE_IS);
ASSERT_EQ(locker.getLockMode(resourceIdReplicationStateTransitionLock), MODE_IS);
@@ -896,7 +900,8 @@ TEST_F(LockerImplTest, RSTLModeISWithTwoPhaseLockingCanBeUnlockedWhenPrepared) {
}
TEST_F(LockerImplTest, RSTLTwoPhaseLockingBehaviorModeIS) {
- LockerImpl locker;
+ auto opCtx = makeOperationContext();
+ LockerImpl locker(opCtx->getServiceContext());
locker.lock(resourceIdReplicationStateTransitionLock, MODE_IS);
ASSERT_EQ(locker.getLockMode(resourceIdReplicationStateTransitionLock), MODE_IS);
@@ -922,8 +927,8 @@ TEST_F(LockerImplTest, OverrideLockRequestTimeout) {
const ResourceId resIdFirstDB(RESOURCE_DATABASE, "FirstDB"_sd);
const ResourceId resIdSecondDB(RESOURCE_DATABASE, "SecondDB"_sd);
- LockerImpl locker1;
- LockerImpl locker2;
+ LockerImpl locker1(opCtx->getServiceContext());
+ LockerImpl locker2(opCtx->getServiceContext());
// Set up locker2 to override lock requests' provided timeout if greater than 1000 milliseconds.
locker2.setMaxLockTimeout(Milliseconds(1000));
@@ -959,8 +964,8 @@ TEST_F(LockerImplTest, DoNotWaitForLockAcquisition) {
const ResourceId resIdFirstDB(RESOURCE_DATABASE, "FirstDB"_sd);
const ResourceId resIdSecondDB(RESOURCE_DATABASE, "SecondDB"_sd);
- LockerImpl locker1;
- LockerImpl locker2;
+ LockerImpl locker1(opCtx->getServiceContext());
+ LockerImpl locker2(opCtx->getServiceContext());
// Set up locker2 to immediately return if a lock is unavailable, regardless of supplied
// deadlines in the lock request.
@@ -1015,7 +1020,7 @@ TEST_F(LockerImplTest, GetLockerInfoShouldReportHeldLocks) {
const ResourceId collectionId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
// Take an exclusive lock on the collection.
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
locker.lockGlobal(opCtx.get(), MODE_IX);
locker.lock(dbId, MODE_IX);
locker.lock(collectionId, MODE_X);
@@ -1041,13 +1046,13 @@ TEST_F(LockerImplTest, GetLockerInfoShouldReportPendingLocks) {
const ResourceId collectionId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
// Take an exclusive lock on the collection.
- LockerImpl successfulLocker;
+ LockerImpl successfulLocker(opCtx->getServiceContext());
successfulLocker.lockGlobal(opCtx.get(), MODE_IX);
successfulLocker.lock(dbId, MODE_IX);
successfulLocker.lock(collectionId, MODE_X);
// Now attempt to get conflicting locks.
- LockerImpl conflictingLocker;
+ LockerImpl conflictingLocker(opCtx->getServiceContext());
conflictingLocker.lockGlobal(opCtx.get(), MODE_IS);
conflictingLocker.lock(dbId, MODE_IS);
ASSERT_EQ(LOCK_WAITING,
@@ -1085,7 +1090,7 @@ TEST_F(LockerImplTest, ReaquireLockPendingUnlock) {
const ResourceId resId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
locker.lockGlobal(opCtx.get(), MODE_IS);
locker.lock(resId, MODE_X);
@@ -1115,7 +1120,7 @@ TEST_F(LockerImplTest, AcquireLockPendingUnlockWithCoveredMode) {
const ResourceId resId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
locker.lockGlobal(opCtx.get(), MODE_IS);
locker.lock(resId, MODE_X);
@@ -1145,7 +1150,7 @@ TEST_F(LockerImplTest, ConvertLockPendingUnlock) {
const ResourceId resId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
locker.lockGlobal(opCtx.get(), MODE_IS);
locker.lock(resId, MODE_IX);
@@ -1179,7 +1184,7 @@ TEST_F(LockerImplTest, ConvertLockPendingUnlockAndUnlock) {
const ResourceId resId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
locker.lockGlobal(opCtx.get(), MODE_IS);
locker.lock(resId, MODE_IX);
@@ -1250,7 +1255,7 @@ DEATH_TEST_F(LockerImplTest,
const ResourceId resId(RESOURCE_COLLECTION, "TestDB.collection"_sd);
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
locker.lockGlobal(opCtx.get(), MODE_IX);
locker.lock(resId, MODE_X);
diff --git a/src/mongo/db/concurrency/lock_stats_test.cpp b/src/mongo/db/concurrency/lock_stats_test.cpp
index c06bb260b9b..bce10971dae 100644
--- a/src/mongo/db/concurrency/lock_stats_test.cpp
+++ b/src/mongo/db/concurrency/lock_stats_test.cpp
@@ -165,7 +165,7 @@ void assertGlobalAcquisitionStats(OperationContext* opCtx, ResourceId rid) {
reportGlobalLockingStats(&stats);
ASSERT_EQUALS(0, stats.get(rid, LockMode::MODE_IX).numAcquisitions);
- LockerImpl locker;
+ LockerImpl locker(opCtx->getServiceContext());
if (rid == resourceIdGlobal) {
locker.lockGlobal(opCtx, LockMode::MODE_IX);
} else {
@@ -205,8 +205,8 @@ TEST_F(LockStatsTest, ServerStatus) {
ASSERT_EQUALS(0, builder.done().nFields());
// Take the global, PBWM and RSTL locks in MODE_IX to create acquisition stats for them.
- LockerImpl locker;
auto opCtx = makeOperationContext();
+ LockerImpl locker(opCtx->getServiceContext());
locker.lockGlobal(opCtx.get(), LockMode::MODE_IX);
locker.lock(resourceIdParallelBatchWriterMode, LockMode::MODE_IX);
locker.lock(resourceIdReplicationStateTransitionLock, LockMode::MODE_IX);
diff --git a/src/mongo/db/db_raii_multi_collection_test.cpp b/src/mongo/db/db_raii_multi_collection_test.cpp
index 1ad777c076a..f64224deb8a 100644
--- a/src/mongo/db/db_raii_multi_collection_test.cpp
+++ b/src/mongo/db/db_raii_multi_collection_test.cpp
@@ -51,7 +51,7 @@ public:
ClientAndCtx makeClientWithLocker(const std::string& clientName) {
auto client = getServiceContext()->makeClient(clientName);
auto opCtx = client->makeOperationContext();
- client->swapLockState(std::make_unique<LockerImpl>());
+ client->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
return std::make_pair(std::move(client), std::move(opCtx));
}
diff --git a/src/mongo/db/db_raii_test.cpp b/src/mongo/db/db_raii_test.cpp
index 3c578a29370..0e0ae201252 100644
--- a/src/mongo/db/db_raii_test.cpp
+++ b/src/mongo/db/db_raii_test.cpp
@@ -57,7 +57,7 @@ public:
ClientAndCtx makeClientWithLocker(const std::string& clientName) {
auto client = getServiceContext()->makeClient(clientName);
auto opCtx = client->makeOperationContext();
- client->swapLockState(std::make_unique<LockerImpl>());
+ client->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
return std::make_pair(std::move(client), std::move(opCtx));
}
diff --git a/src/mongo/db/exec/sbe/abt/sbe_abt_diff_test.cpp b/src/mongo/db/exec/sbe/abt/sbe_abt_diff_test.cpp
index 3112ec3c88a..252b7ce52b4 100644
--- a/src/mongo/db/exec/sbe/abt/sbe_abt_diff_test.cpp
+++ b/src/mongo/db/exec/sbe/abt/sbe_abt_diff_test.cpp
@@ -133,7 +133,7 @@ public:
void onDestroyClient(Client* client) final {}
void onCreateOperationContext(OperationContext* opCtx) override {
- opCtx->setLockState(std::make_unique<LockerImpl>());
+ opCtx->setLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
}
void onDestroyOperationContext(OperationContext* opCtx) final {}
diff --git a/src/mongo/db/mongod_main.cpp b/src/mongo/db/mongod_main.cpp
index 02c2ba93904..bce1bc1815c 100644
--- a/src/mongo/db/mongod_main.cpp
+++ b/src/mongo/db/mongod_main.cpp
@@ -1412,7 +1412,7 @@ void shutdownTask(const ShutdownTaskArgs& shutdownArgs) {
// of this function to prevent any operations from running that need a lock.
//
LOGV2(4784929, "Acquiring the global lock for shutdown");
- LockerImpl* globalLocker = new LockerImpl();
+ LockerImpl* globalLocker = new LockerImpl(serviceContext);
globalLocker->lockGlobal(nullptr, MODE_X);
// Global storage engine may not be started in all cases before we exit
diff --git a/src/mongo/db/pipeline/process_interface/shardsvr_process_interface_test.cpp b/src/mongo/db/pipeline/process_interface/shardsvr_process_interface_test.cpp
index ba3fe548407..5c3f7eebf97 100644
--- a/src/mongo/db/pipeline/process_interface/shardsvr_process_interface_test.cpp
+++ b/src/mongo/db/pipeline/process_interface/shardsvr_process_interface_test.cpp
@@ -44,7 +44,7 @@ TEST_F(ShardedProcessInterfaceTest, TestInsert) {
setupNShards(2);
// Need a real locker for storage operations.
- getClient()->swapLockState(std::make_unique<LockerImpl>());
+ getClient()->swapLockState(std::make_unique<LockerImpl>(expCtx()->opCtx->getServiceContext()));
const NamespaceString kOutNss = NamespaceString{"unittests-out", "sharded_agg_test"};
auto outStage = DocumentSourceOut::create(kOutNss, expCtx());
diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
index cf24f3712b4..218951db1a9 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
@@ -2203,7 +2203,8 @@ TEST_F(StepDownTest,
// locker to test this, or otherwise stepDown will be granted the lock automatically.
ReplicationStateTransitionLockGuard transitionGuard(opCtx.get(), MODE_X);
ASSERT_TRUE(opCtx->lockState()->isRSTLExclusive());
- auto locker = getClient()->swapLockState(std::make_unique<LockerImpl>());
+ auto locker =
+ getClient()->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
ASSERT_THROWS_CODE(
getReplCoord()->stepDown(opCtx.get(), false, Milliseconds(0), Milliseconds(1000)),
diff --git a/src/mongo/db/service_entry_point_mongod.cpp b/src/mongo/db/service_entry_point_mongod.cpp
index df50322d6c2..f47f6487ba3 100644
--- a/src/mongo/db/service_entry_point_mongod.cpp
+++ b/src/mongo/db/service_entry_point_mongod.cpp
@@ -269,7 +269,7 @@ public:
// It is necessary to lock the client to change the Locker on the OperationContext.
stdx::lock_guard<Client> lk(*opCtx->getClient());
invariant(!opCtx->lockState()->isLocked());
- opCtx->swapLockState(std::make_unique<LockerImpl>(), lk);
+ opCtx->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()), lk);
}
std::unique_ptr<PolymorphicScoped> scopedOperationCompletionShardingActions(
diff --git a/src/mongo/db/storage/storage_engine_init.cpp b/src/mongo/db/storage/storage_engine_init.cpp
index 97f935e32a9..7c345ddcfe6 100644
--- a/src/mongo/db/storage/storage_engine_init.cpp
+++ b/src/mongo/db/storage/storage_engine_init.cpp
@@ -168,29 +168,28 @@ StorageEngine::LastShutdownState initializeStorageEngine(OperationContext* opCtx
auto writeTransactions = gConcurrentWriteTransactions.load();
writeTransactions = writeTransactions == 0 ? DEFAULT_TICKETS_VALUE : writeTransactions;
- // TODO SERVER-64467: Remove the globalServiceContext for TicketHolders
- auto serviceContext = getGlobalServiceContext();
- auto& ticketHolders = ticketHoldersDecoration(serviceContext);
+ auto svcCtx = opCtx->getServiceContext();
+ auto& ticketHolders = TicketHolders::get(svcCtx);
if (feature_flags::gFeatureFlagExecutionControl.isEnabledAndIgnoreFCV()) {
LOGV2_DEBUG(5190400, 1, "Enabling new ticketing policies");
switch (gTicketQueueingPolicy) {
case QueueingPolicyEnum::Semaphore:
LOGV2_DEBUG(6382201, 1, "Using Semaphore-based ticketing scheduler");
ticketHolders.setGlobalThrottling(
- std::make_unique<SemaphoreTicketHolder>(readTransactions, serviceContext),
- std::make_unique<SemaphoreTicketHolder>(writeTransactions, serviceContext));
+ std::make_unique<SemaphoreTicketHolder>(readTransactions, svcCtx),
+ std::make_unique<SemaphoreTicketHolder>(writeTransactions, svcCtx));
break;
case QueueingPolicyEnum::FifoQueue:
LOGV2_DEBUG(6382200, 1, "Using FIFO queue-based ticketing scheduler");
ticketHolders.setGlobalThrottling(
- std::make_unique<FifoTicketHolder>(readTransactions, serviceContext),
- std::make_unique<FifoTicketHolder>(writeTransactions, serviceContext));
+ std::make_unique<FifoTicketHolder>(readTransactions, svcCtx),
+ std::make_unique<FifoTicketHolder>(writeTransactions, svcCtx));
break;
}
} else {
ticketHolders.setGlobalThrottling(
- std::make_unique<SemaphoreTicketHolder>(readTransactions, serviceContext),
- std::make_unique<SemaphoreTicketHolder>(writeTransactions, serviceContext));
+ std::make_unique<SemaphoreTicketHolder>(readTransactions, svcCtx),
+ std::make_unique<SemaphoreTicketHolder>(writeTransactions, svcCtx));
}
}
@@ -255,13 +254,6 @@ void shutdownGlobalStorageEngineCleanly(ServiceContext* service,
lockFile->clearPidAndUnlock();
lockFile = boost::none;
}
- // TODO SERVER-64467: Remove the globalServiceContext for TicketHolders
- // Cleanup the ticket holders.
- if (hasGlobalServiceContext() && !forRestart) {
- auto serviceContext = getGlobalServiceContext();
- auto& ticketHolders = ticketHoldersDecoration(serviceContext);
- ticketHolders.setGlobalThrottling(nullptr, nullptr);
- }
}
} /* namespace */
@@ -412,7 +404,7 @@ public:
void onDestroyClient(Client* client) override{};
void onCreateOperationContext(OperationContext* opCtx) {
// Use a fully fledged lock manager even when the storage engine is not set.
- opCtx->setLockState(std::make_unique<LockerImpl>());
+ opCtx->setLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()));
auto service = opCtx->getServiceContext();
diff --git a/src/mongo/db/storage/ticketholders.cpp b/src/mongo/db/storage/ticketholders.cpp
index 1fcc8371946..36dc23f0a7a 100644
--- a/src/mongo/db/storage/ticketholders.cpp
+++ b/src/mongo/db/storage/ticketholders.cpp
@@ -30,27 +30,34 @@
#include "mongo/db/storage/ticketholders.h"
#include "mongo/util/concurrency/ticketholder.h"
+namespace {
+const auto ticketHoldersDecoration =
+ mongo::ServiceContext::declareDecoration<mongo::TicketHolders>();
+}
+
namespace mongo {
Status TicketHolders::updateConcurrentWriteTransactions(const int& newWriteTransactions) {
- if (hasGlobalServiceContext()) {
- auto serviceContext = getGlobalServiceContext();
- auto& ticketHolders = ticketHoldersDecoration(serviceContext);
- auto& writer = ticketHolders._openWriteTransaction;
- if (writer) {
- return writer->resize(newWriteTransactions);
+ if (auto client = Client::getCurrent()) {
+ if (auto svcCtx = client->getServiceContext()) {
+ auto& ticketHolders = TicketHolders::get(svcCtx);
+ auto& writer = ticketHolders._openWriteTransaction;
+ if (writer) {
+ return writer->resize(newWriteTransactions);
+ }
}
}
return Status::OK();
};
Status TicketHolders::updateConcurrentReadTransactions(const int& newReadTransactions) {
- if (hasGlobalServiceContext()) {
- auto serviceContext = getGlobalServiceContext();
- auto& ticketHolders = ticketHoldersDecoration(serviceContext);
- auto& reader = ticketHolders._openReadTransaction;
- if (reader) {
- return reader->resize(newReadTransactions);
+ if (auto client = Client::getCurrent()) {
+ if (auto svcCtx = client->getServiceContext()) {
+ auto& ticketHolders = TicketHolders::get(svcCtx);
+ auto& reader = ticketHolders._openReadTransaction;
+ if (reader) {
+ return reader->resize(newReadTransactions);
+ }
}
}
return Status::OK();
@@ -74,8 +81,12 @@ TicketHolder* TicketHolders::getTicketHolder(LockMode mode) {
}
}
-const Decorable<ServiceContext>::Decoration<TicketHolders> ticketHoldersDecoration =
- ServiceContext::declareDecoration<TicketHolders>();
+TicketHolders& TicketHolders::get(ServiceContext* svcCtx) {
+ return ticketHoldersDecoration(svcCtx);
+}
+TicketHolders& TicketHolders::get(ServiceContext& svcCtx) {
+ return ticketHoldersDecoration(svcCtx);
+}
} // namespace mongo
diff --git a/src/mongo/db/storage/ticketholders.h b/src/mongo/db/storage/ticketholders.h
index 31fdfb8db32..cdaee0f7315 100644
--- a/src/mongo/db/storage/ticketholders.h
+++ b/src/mongo/db/storage/ticketholders.h
@@ -45,6 +45,8 @@ public:
static Status updateConcurrentReadTransactions(const int& newReadTransactions);
+ static TicketHolders& get(ServiceContext* svcCtx);
+ static TicketHolders& get(ServiceContext& svcCtx);
/**
* Sets the TicketHolder implementation to use to obtain tickets from 'reading' (for MODE_S and
* MODE_IS), and from 'writing' (for MODE_IX) in order to throttle database access. There is no
@@ -62,9 +64,4 @@ private:
std::unique_ptr<TicketHolder> _openReadTransaction;
};
-/**
- * Decorated accessor to the 'TicketHolders' stored in 'ServiceContext'.
- */
-extern const Decorable<ServiceContext>::Decoration<TicketHolders> ticketHoldersDecoration;
-
} // namespace mongo
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
index 2763f082246..d26015451c9 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
@@ -604,10 +604,9 @@ void WiredTigerKVEngine::notifyStartupComplete() {
WiredTigerUtil::notifyStartupComplete();
}
-void WiredTigerKVEngine::appendGlobalStats(BSONObjBuilder& b) {
+void WiredTigerKVEngine::appendGlobalStats(OperationContext* opCtx, BSONObjBuilder& b) {
BSONObjBuilder bb(b.subobjStart("concurrentTransactions"));
- auto serviceContext = getGlobalServiceContext();
- auto& ticketHolders = ticketHoldersDecoration(serviceContext);
+ auto& ticketHolders = TicketHolders::get(opCtx->getServiceContext());
{
auto writer = ticketHolders.getTicketHolder(MODE_IX);
BSONObjBuilder bbb(bb.subobjStart("write"));
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
index 7360c65f3ec..688db855b74 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
@@ -316,7 +316,7 @@ public:
return _oplogManager.get();
}
- static void appendGlobalStats(BSONObjBuilder& b);
+ static void appendGlobalStats(OperationContext* opCtx, BSONObjBuilder& b);
Timestamp getStableTimestamp() const override;
Timestamp getOldestTimestamp() const override;
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_server_status.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_server_status.cpp
index be978059c17..caf44b7c2bd 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_server_status.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_server_status.cpp
@@ -90,7 +90,7 @@ BSONObj WiredTigerServerStatusSection::generateSection(OperationContext* opCtx,
bob.append("reason", status.reason());
}
- WiredTigerKVEngine::appendGlobalStats(bob);
+ WiredTigerKVEngine::appendGlobalStats(opCtx, bob);
WiredTigerKVEngine* engine = checked_cast<WiredTigerKVEngine*>(
opCtx->getServiceContext()->getStorageEngine()->getEngine());
diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp
index 298cf5b3cc2..84e83664b92 100644
--- a/src/mongo/db/transaction_participant.cpp
+++ b/src/mongo/db/transaction_participant.cpp
@@ -1161,7 +1161,7 @@ TransactionParticipant::TxnResources::TxnResources(WithLock wl,
_ruState = opCtx->getWriteUnitOfWork()->release();
opCtx->setWriteUnitOfWork(nullptr);
- _locker = opCtx->swapLockState(std::make_unique<LockerImpl>(), wl);
+ _locker = opCtx->swapLockState(std::make_unique<LockerImpl>(opCtx->getServiceContext()), wl);
// Inherit the locking setting from the original one.
opCtx->lockState()->setShouldConflictWithSecondaryBatchApplication(
_locker->shouldConflictWithSecondaryBatchApplication());