Example #1
0
TEST(LockManager, ConflictingConversionInTheMiddle) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker;
    TrackingLockGrantNotification notify;

    LockRequest request[3];
    for (int i = 0; i < 3; i++) {
        request[i].initNew(&locker, &notify);
        lockMgr.lock(resId, &request[i], MODE_S);
    }

    // Upgrade the one in the middle (not the first one)
    ASSERT(LOCK_WAITING == lockMgr.convert(resId, &request[1], MODE_X));

    ASSERT(notify.numNotifies == 0);

    // Release the two shared modes
    lockMgr.unlock(&request[0]);
    ASSERT(notify.numNotifies == 0);

    lockMgr.unlock(&request[2]);
    ASSERT(notify.numNotifies == 1);

    ASSERT(request[1].mode == MODE_X);

    // Request 1 should be unlocked twice
    lockMgr.unlock(&request[1]);
    lockMgr.unlock(&request[1]);
}
Example #2
0
TEST(LockManager, CancelWaitingConversionStrongModes) {
    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_S));
    ASSERT(request1.numNotifies == 0);

    // Second request is granted right away
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request2, MODE_S));
    ASSERT(request2.numNotifies == 0);

    // Convert second request to conflicting
    ASSERT(LOCK_WAITING == lockMgr.convert(resId, &request2, MODE_X));
    ASSERT(request2.mode == MODE_S);
    ASSERT(request2.convertMode == MODE_X);
    ASSERT(request2.numNotifies == 0);

    // Cancel the conflicting upgrade
    lockMgr.unlock(&request2);
    ASSERT(request2.mode == MODE_S);
    ASSERT(request2.convertMode == MODE_NONE);
    ASSERT(request2.numNotifies == 0);

    // Free the remaining locks so the LockManager destructor does not complain
    lockMgr.unlock(&request1);
    lockMgr.unlock(&request2);
}
Example #3
0
TEST(LockManager, ConflictingConversion) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker1;
    MMAPV1LockerImpl locker2;

    LockRequestCombo request1(&locker1);
    LockRequestCombo request2(&locker2);

    // The S requests are granted right away
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_S));
    ASSERT(request1.numNotifies == 0);

    ASSERT(LOCK_OK == lockMgr.lock(resId, &request2, MODE_S));
    ASSERT(request2.numNotifies == 0);

    // Convert first request to conflicting
    ASSERT(LOCK_WAITING == lockMgr.convert(resId, &request1, MODE_X));
    ASSERT(request1.numNotifies == 0);

    // Free the second lock and make sure the first is granted
    lockMgr.unlock(&request2);
    ASSERT(request1.mode == MODE_X);
    ASSERT(request1.numNotifies == 1);
    ASSERT(request2.numNotifies == 0);

    // Frees the first reference, mode remains X
    lockMgr.unlock(&request1);
    ASSERT(request1.mode == MODE_X);
    ASSERT(request1.recursiveCount == 1);

    lockMgr.unlock(&request1);
}
Example #4
0
TEST(LockManager, GrantRecursiveNonCompatibleConvertDown) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker;
    LockRequestCombo request(&locker);

    ASSERT(LOCK_OK == lockMgr.lock(resId, &request, MODE_X));
    ASSERT(request.mode == MODE_X);
    ASSERT(request.recursiveCount == 1);
    ASSERT(request.numNotifies == 0);

    // Acquire again, in *non-compatible*, but less strict mode
    ASSERT(LOCK_OK == lockMgr.convert(resId, &request, MODE_S));
    ASSERT(request.mode == MODE_X);
    ASSERT(request.recursiveCount == 2);
    ASSERT(request.numNotifies == 0);

    // Release first acquire
    lockMgr.unlock(&request);
    ASSERT(request.mode == MODE_X);
    ASSERT(request.recursiveCount == 1);

    // Release second acquire
    lockMgr.unlock(&request);
    ASSERT(request.recursiveCount == 0);
}
Example #5
0
TEST(LockManager, ConvertUpgrade) {
    LockManager lockMgr;
    const ResourceId resId(RESOURCE_COLLECTION, std::string("TestDB.collection"));

    MMAPV1LockerImpl locker1;
    LockRequestCombo request1(&locker1);
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_S));

    MMAPV1LockerImpl locker2;
    LockRequestCombo request2(&locker2);
    ASSERT(LOCK_OK == lockMgr.lock(resId, &request2, MODE_S));

    // Upgrade the S lock to X
    ASSERT(LOCK_WAITING == lockMgr.convert(resId, &request1, MODE_X));

    ASSERT(!lockMgr.unlock(&request1));
    ASSERT(lockMgr.unlock(&request1));

    ASSERT(lockMgr.unlock(&request2));
}