summaryrefslogtreecommitdiff
path: root/src/mongo/db/db_raii.cpp
diff options
context:
space:
mode:
authorCharlie Swanson <charlie.swanson@mongodb.com>2017-03-02 13:54:24 -0500
committerCharlie Swanson <charlie.swanson@mongodb.com>2017-03-15 11:03:44 -0400
commitf05b9437fbdc53deecf55ed3c20e36af3d733953 (patch)
tree8b66acc133f83f27ef00f31600538f225ec2746a /src/mongo/db/db_raii.cpp
parenta1f15dfd788a78da77bda6675132d4144691fce1 (diff)
downloadmongo-f05b9437fbdc53deecf55ed3c20e36af3d733953.tar.gz
SERVER-22541 Refactor RAII locking helpers.
Removes the class 'ScopedTransaction' and moves the responsibility of abandoning the snapshot onto the GlobalLock class. Also renames the AutoGetCollectionForRead class to AutoGetCollectionForReadCommand, and adds a new AutoGetCollectionForRead class. Unlike AutoGetCollectionForReadCommand, this new class will not update the namespace on the CurrentOp object, nor will it add an entry to Top.
Diffstat (limited to 'src/mongo/db/db_raii.cpp')
-rw-r--r--src/mongo/db/db_raii.cpp92
1 files changed, 48 insertions, 44 deletions
diff --git a/src/mongo/db/db_raii.cpp b/src/mongo/db/db_raii.cpp
index 051d9141ebf..84b6584b540 100644
--- a/src/mongo/db/db_raii.cpp
+++ b/src/mongo/db/db_raii.cpp
@@ -42,7 +42,7 @@
namespace mongo {
AutoGetDb::AutoGetDb(OperationContext* opCtx, StringData ns, LockMode mode)
- : _dbLock(opCtx->lockState(), ns, mode), _db(dbHolder().get(opCtx, ns)) {}
+ : _dbLock(opCtx, ns, mode), _db(dbHolder().get(opCtx, ns)) {}
AutoGetCollection::AutoGetCollection(OperationContext* opCtx,
const NamespaceString& nss,
@@ -62,9 +62,7 @@ AutoGetCollection::AutoGetCollection(OperationContext* opCtx,
}
AutoGetOrCreateDb::AutoGetOrCreateDb(OperationContext* opCtx, StringData ns, LockMode mode)
- : _transaction(opCtx, MODE_IX),
- _dbLock(opCtx->lockState(), ns, mode),
- _db(dbHolder().get(opCtx, ns)) {
+ : _dbLock(opCtx, ns, mode), _db(dbHolder().get(opCtx, ns)) {
invariant(mode == MODE_IX || mode == MODE_X);
_justCreated = false;
// If the database didn't exist, relock in MODE_X
@@ -79,36 +77,14 @@ AutoGetOrCreateDb::AutoGetOrCreateDb(OperationContext* opCtx, StringData ns, Loc
AutoGetCollectionForRead::AutoGetCollectionForRead(OperationContext* opCtx,
const NamespaceString& nss,
- AutoGetCollection::ViewMode viewMode)
- : _opCtx(opCtx), _transaction(opCtx, MODE_IS) {
- {
- _autoColl.emplace(opCtx, nss, MODE_IS, MODE_IS, viewMode);
-
- auto curOp = CurOp::get(_opCtx);
- stdx::lock_guard<Client> lk(*_opCtx->getClient());
-
- // TODO: OldClientContext legacy, needs to be removed
- curOp->ensureStarted();
- curOp->setNS_inlock(nss.ns());
-
- // At this point, we are locked in shared mode for the database by the DB lock in the
- // constructor, so it is safe to load the DB pointer.
- if (_autoColl->getDb()) {
- // TODO: OldClientContext legacy, needs to be removed
- curOp->enter_inlock(nss.ns().c_str(), _autoColl->getDb()->getProfilingLevel());
- }
- }
+ AutoGetCollection::ViewMode viewMode) {
+ _autoColl.emplace(opCtx, nss, MODE_IS, MODE_IS, viewMode);
// Note: this can yield.
- _ensureMajorityCommittedSnapshotIsValid(nss);
-
- // We have both the DB and collection locked, which is the prerequisite to do a stable shard
- // version check, but we'd like to do the check after we have a satisfactory snapshot.
- auto css = CollectionShardingState::get(opCtx, nss);
- css->checkShardVersionOrThrow(opCtx);
+ _ensureMajorityCommittedSnapshotIsValid(nss, opCtx);
}
-AutoGetCollectionForRead::~AutoGetCollectionForRead() {
+AutoGetCollectionForReadCommand::~AutoGetCollectionForReadCommand() {
// Report time spent in read lock
auto currentOp = CurOp::get(_opCtx);
Top::get(_opCtx->getClient()->getServiceContext())
@@ -121,7 +97,8 @@ AutoGetCollectionForRead::~AutoGetCollectionForRead() {
currentOp->getReadWriteType());
}
-void AutoGetCollectionForRead::_ensureMajorityCommittedSnapshotIsValid(const NamespaceString& nss) {
+void AutoGetCollectionForRead::_ensureMajorityCommittedSnapshotIsValid(const NamespaceString& nss,
+ OperationContext* opCtx) {
while (true) {
auto coll = _autoColl->getCollection();
if (!coll) {
@@ -131,7 +108,7 @@ void AutoGetCollectionForRead::_ensureMajorityCommittedSnapshotIsValid(const Nam
if (!minSnapshot) {
return;
}
- auto mySnapshot = _opCtx->recoveryUnit()->getMajorityCommittedSnapshot();
+ auto mySnapshot = opCtx->recoveryUnit()->getMajorityCommittedSnapshot();
if (!mySnapshot) {
return;
}
@@ -142,31 +119,58 @@ void AutoGetCollectionForRead::_ensureMajorityCommittedSnapshotIsValid(const Nam
// Yield locks.
_autoColl = boost::none;
- repl::ReplicationCoordinator::get(_opCtx)->waitUntilSnapshotCommitted(_opCtx, *minSnapshot);
+ repl::ReplicationCoordinator::get(opCtx)->waitUntilSnapshotCommitted(opCtx, *minSnapshot);
- uassertStatusOK(_opCtx->recoveryUnit()->setReadFromMajorityCommittedSnapshot());
+ uassertStatusOK(opCtx->recoveryUnit()->setReadFromMajorityCommittedSnapshot());
{
- stdx::lock_guard<Client> lk(*_opCtx->getClient());
- CurOp::get(_opCtx)->yielded();
+ stdx::lock_guard<Client> lk(*opCtx->getClient());
+ CurOp::get(opCtx)->yielded();
}
// Relock.
- _autoColl.emplace(_opCtx, nss, MODE_IS);
+ _autoColl.emplace(opCtx, nss, MODE_IS);
+ }
+}
+
+AutoGetCollectionForReadCommand::AutoGetCollectionForReadCommand(
+ OperationContext* opCtx, const NamespaceString& nss, AutoGetCollection::ViewMode viewMode)
+ : _opCtx(opCtx) {
+ {
+ _autoCollForRead.emplace(opCtx, nss, viewMode);
+
+ auto curOp = CurOp::get(_opCtx);
+ stdx::lock_guard<Client> lk(*_opCtx->getClient());
+
+ // TODO: OldClientContext legacy, needs to be removed
+ curOp->ensureStarted();
+ curOp->setNS_inlock(nss.ns());
+
+ // At this point, we are locked in shared mode for the database by the DB lock in the
+ // constructor, so it is safe to load the DB pointer.
+ if (_autoCollForRead->getDb()) {
+ // TODO: OldClientContext legacy, needs to be removed
+ curOp->enter_inlock(nss.ns().c_str(), _autoCollForRead->getDb()->getProfilingLevel());
+ }
}
+
+ // We have both the DB and collection locked, which is the prerequisite to do a stable shard
+ // version check, but we'd like to do the check after we have a satisfactory snapshot.
+ auto css = CollectionShardingState::get(opCtx, nss);
+ css->checkShardVersionOrThrow(opCtx);
}
-AutoGetCollectionOrViewForRead::AutoGetCollectionOrViewForRead(OperationContext* opCtx,
- const NamespaceString& nss)
- : AutoGetCollectionForRead(opCtx, nss, AutoGetCollection::ViewMode::kViewsPermitted),
- _view(_autoColl->getDb() && !getCollection()
- ? _autoColl->getDb()->getViewCatalog()->lookup(opCtx, nss.ns())
+AutoGetCollectionOrViewForReadCommand::AutoGetCollectionOrViewForReadCommand(
+ OperationContext* opCtx, const NamespaceString& nss)
+ : AutoGetCollectionForReadCommand(opCtx, nss, AutoGetCollection::ViewMode::kViewsPermitted),
+ _view(_autoCollForRead->getDb() && !getCollection()
+ ? _autoCollForRead->getDb()->getViewCatalog()->lookup(opCtx, nss.ns())
: nullptr) {}
-void AutoGetCollectionOrViewForRead::releaseLocksForView() noexcept {
+void AutoGetCollectionOrViewForReadCommand::releaseLocksForView() noexcept {
invariant(_view);
_view = nullptr;
- _autoColl = boost::none;
+ _autoCollForRead = boost::none;
}
OldClientContext::OldClientContext(OperationContext* opCtx,