summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeert Bosch <geert@mongodb.com>2015-04-24 17:10:08 -0400
committerGeert Bosch <geert@mongodb.com>2015-04-24 20:10:21 -0400
commit33974f928d1a970b7b373e8fa8b97ba13ce14b2e (patch)
tree18865d65d83425d2d119a90e9083c512f12e523c /src
parent36642967c8cdb2b64e5ce8e87966abb329bdf369 (diff)
downloadmongo-33974f928d1a970b7b373e8fa8b97ba13ce14b2e.tar.gz
SERVER-17770: Replace CollectionLock::relockWithMode by relockAsDatabaseExclusive
Previous version was confusing. This really has just a single purpose, so make that clear.
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/commands/find_and_modify.cpp2
-rw-r--r--src/mongo/db/concurrency/d_concurrency.cpp7
-rw-r--r--src/mongo/db/concurrency/d_concurrency.h11
-rw-r--r--src/mongo/db/db_raii.cpp12
4 files changed, 21 insertions, 11 deletions
diff --git a/src/mongo/db/commands/find_and_modify.cpp b/src/mongo/db/commands/find_and_modify.cpp
index b8e76b8e0a2..8a5f15225cb 100644
--- a/src/mongo/db/commands/find_and_modify.cpp
+++ b/src/mongo/db/commands/find_and_modify.cpp
@@ -494,7 +494,7 @@ namespace {
if (!collection && args.isUpsert()) {
// Release the collection lock and reacquire a lock on the database
// in exclusive mode in order to create the collection.
- collLock.relockWithMode(MODE_X, autoDb.lock());
+ collLock.relockAsDatabaseExclusive(autoDb.lock());
collection = autoDb.getDb()->getCollection(nsString.ns());
Status isPrimaryAfterRelock = checkCanAcceptWritesForDatabase(nsString);
if (!isPrimaryAfterRelock.isOK()) {
diff --git a/src/mongo/db/concurrency/d_concurrency.cpp b/src/mongo/db/concurrency/d_concurrency.cpp
index 5882c5a1950..b1eaa7ddc30 100644
--- a/src/mongo/db/concurrency/d_concurrency.cpp
+++ b/src/mongo/db/concurrency/d_concurrency.cpp
@@ -181,15 +181,16 @@ namespace {
}
}
- void Lock::CollectionLock::relockWithMode(LockMode mode, Lock::DBLock& dbLock) {
+ void Lock::CollectionLock::relockAsDatabaseExclusive(Lock::DBLock& dbLock) {
if (supportsDocLocking() || enableCollectionLocking) {
_lockState->unlock(_id);
}
- dbLock.relockWithMode(mode);
+ dbLock.relockWithMode(MODE_X);
if (supportsDocLocking() || enableCollectionLocking) {
- _lockState->lock(_id, mode);
+ // don't need the lock, but need something to unlock in the destructor
+ _lockState->lock(_id, MODE_IX);
}
}
diff --git a/src/mongo/db/concurrency/d_concurrency.h b/src/mongo/db/concurrency/d_concurrency.h
index 374373e74f9..6569aae2b10 100644
--- a/src/mongo/db/concurrency/d_concurrency.h
+++ b/src/mongo/db/concurrency/d_concurrency.h
@@ -216,7 +216,16 @@ namespace mongo {
CollectionLock(Locker* lockState, StringData ns, LockMode mode);
~CollectionLock();
- void relockWithMode(LockMode mode, Lock::DBLock& dblock);
+ /**
+ * When holding the collection in MODE_IX or MODE_X, calling this will release the
+ * collection and database locks, and relocks the database in MODE_X. This is typically
+ * used if the collection still needs to be created. Upgrading would not be safe as
+ * it could lead to deadlock, similarly for relocking the database without releasing
+ * the collection lock. The collection lock will also be reacquired even though it is
+ * not really needed, as it simplifies invariant checking: the CollectionLock class
+ * has as invariant that a collection lock is being held.
+ */
+ void relockAsDatabaseExclusive(Lock::DBLock& dbLock);
private:
const ResourceId _id;
diff --git a/src/mongo/db/db_raii.cpp b/src/mongo/db/db_raii.cpp
index 597c1ca6a28..937b474ebb2 100644
--- a/src/mongo/db/db_raii.cpp
+++ b/src/mongo/db/db_raii.cpp
@@ -185,12 +185,12 @@ namespace mongo {
_autodb(opCtx, _nss.db(), MODE_IX),
_collk(opCtx->lockState(), ns, MODE_IX),
_c(opCtx, ns, _autodb.getDb(), _autodb.justCreated()) {
- _collection = _c.db()->getCollection( ns );
- if ( !_collection && !_autodb.justCreated() ) {
- // relock in MODE_X
- _collk.relockWithMode( MODE_X, _autodb.lock() );
- Database* db = dbHolder().get(_txn, ns );
- invariant( db == _c.db() );
+ _collection = _c.db()->getCollection(ns);
+ if (!_collection && !_autodb.justCreated()) {
+ // relock database in MODE_X to allow collection creation
+ _collk.relockAsDatabaseExclusive(_autodb.lock());
+ Database* db = dbHolder().get(_txn, ns);
+ invariant(db == _c.db());
}
}