diff options
author | Geert Bosch <geert@mongodb.com> | 2015-04-24 17:10:08 -0400 |
---|---|---|
committer | Geert Bosch <geert@mongodb.com> | 2015-04-24 20:10:21 -0400 |
commit | 33974f928d1a970b7b373e8fa8b97ba13ce14b2e (patch) | |
tree | 18865d65d83425d2d119a90e9083c512f12e523c /src | |
parent | 36642967c8cdb2b64e5ce8e87966abb329bdf369 (diff) | |
download | mongo-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.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/concurrency/d_concurrency.cpp | 7 | ||||
-rw-r--r-- | src/mongo/db/concurrency/d_concurrency.h | 11 | ||||
-rw-r--r-- | src/mongo/db/db_raii.cpp | 12 |
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()); } } |