diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2016-05-31 12:39:51 +0300 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2016-06-15 13:57:58 -0400 |
commit | a481e3a9987a8dc7059402c66dd22bfe51d1a818 (patch) | |
tree | 9fe137eff8151bbda295e1f7096e07591261b09d | |
parent | b968ee2da9478d13408c83f606194caec34ea169 (diff) | |
download | mongo-a481e3a9987a8dc7059402c66dd22bfe51d1a818.tar.gz |
SERVER-24316 Add lock conversion cancellation unit-test
This change adds a unit-test to ensure that upgrade from 'weak mode' to
'strong mode' preserves the grant counts correctly. It also tightens the
assertions around lock mode conversion.
-rw-r--r-- | src/mongo/db/concurrency/lock_manager.cpp | 1 | ||||
-rw-r--r-- | src/mongo/db/concurrency/lock_manager_test.cpp | 37 |
2 files changed, 37 insertions, 1 deletions
diff --git a/src/mongo/db/concurrency/lock_manager.cpp b/src/mongo/db/concurrency/lock_manager.cpp index b2b04e788ef..6d2450086fe 100644 --- a/src/mongo/db/concurrency/lock_manager.cpp +++ b/src/mongo/db/concurrency/lock_manager.cpp @@ -619,6 +619,7 @@ bool LockManager::unlock(LockRequest* request) { } else if (request->status == LockRequest::STATUS_CONVERTING) { // This cancels a pending convert request invariant(request->recursiveCount > 0); + invariant(lock->conversionsCount > 0); // Lock only goes from GRANTED to CONVERTING, so cancelling the conversion request // brings it back to the previous granted mode. diff --git a/src/mongo/db/concurrency/lock_manager_test.cpp b/src/mongo/db/concurrency/lock_manager_test.cpp index aa2edef04b4..218dd6227ad 100644 --- a/src/mongo/db/concurrency/lock_manager_test.cpp +++ b/src/mongo/db/concurrency/lock_manager_test.cpp @@ -414,7 +414,42 @@ TEST(LockManager, ConflictCancelMultipleWaiting) { lockMgr.unlock(&request[0]); } -TEST(LockManager, ConflictCancelWaitingConversion) { +TEST(LockManager, CancelWaitingConversionWeakModes) { + LockManager lockMgr; + const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection")); + + MMAPV1LockerImpl locker1; + MMAPV1LockerImpl locker2; + + LockRequestCombo request1(&locker1); + LockRequestCombo request2(&locker2); + + // First request granted right away + ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_IS)); + ASSERT(request1.numNotifies == 0); + + // Second request is granted right away + ASSERT(LOCK_OK == lockMgr.lock(resId, &request2, MODE_IX)); + ASSERT(request2.numNotifies == 0); + + // Convert first request to conflicting + ASSERT(LOCK_WAITING == lockMgr.convert(resId, &request1, MODE_S)); + ASSERT(request1.mode == MODE_IS); + ASSERT(request1.convertMode == MODE_S); + ASSERT(request1.numNotifies == 0); + + // Cancel the conflicting conversion + lockMgr.unlock(&request1); + ASSERT(request1.mode == MODE_IS); + ASSERT(request1.convertMode == MODE_NONE); + ASSERT(request1.numNotifies == 0); + + // Free the remaining locks so the LockManager destructor does not complain + lockMgr.unlock(&request1); + lockMgr.unlock(&request2); +} + +TEST(LockManager, CancelWaitingConversionStrongModes) { LockManager lockMgr; const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection")); |