bool LockerImpl<IsForMMAPV1>::isDbLockedForMode(StringData dbName, LockMode mode) const { invariant(nsIsDbOnly(dbName)); if (isW()) return true; if (isR() && isSharedLockMode(mode)) return true; const ResourceId resIdDb(RESOURCE_DATABASE, dbName); return isLockHeldForMode(resIdDb, mode); }
Lock::DBLock::DBLock(Locker* locker, StringData db, LockMode mode) : _id(RESOURCE_DATABASE, db), _locker(locker), _mode(mode), _globalLock(locker, isSharedLockMode(_mode) ? MODE_IS : MODE_IX, UINT_MAX) { massert(28539, "need a valid database name", !db.empty() && nsIsDbOnly(db)); // Need to acquire the flush lock _locker->lockMMAPV1Flush(); // The check for the admin db is to ensure direct writes to auth collections // are serialized (see SERVER-16092). if ((_id == resourceIdAdminDB) && !isSharedLockMode(_mode)) { _mode = MODE_X; } invariant(LOCK_OK == _locker->lock(_id, _mode)); }
Lock::DBLock::DBLock(OperationContext* opCtx, StringData db, LockMode mode, Date_t deadline) : _id(RESOURCE_DATABASE, db), _opCtx(opCtx), _result(LOCK_INVALID), _mode(mode), _globalLock( opCtx, isSharedLockMode(_mode) ? MODE_IS : MODE_IX, deadline, InterruptBehavior::kThrow) { massert(28539, "need a valid database name", !db.empty() && nsIsDbOnly(db)); // The check for the admin db is to ensure direct writes to auth collections // are serialized (see SERVER-16092). if ((_id == resourceIdAdminDB) && !isSharedLockMode(_mode)) { _mode = MODE_X; } _opCtx->lockState()->lock(_opCtx, _id, _mode, deadline); _result = LOCK_OK; }
Lock::DBLock::DBLock(Locker* lockState, const StringData& db, LockMode mode) : ScopedLock(lockState), _id(RESOURCE_DATABASE, db), _lockState(lockState), _mode(mode) { massert(28539, "need a valid database name", !db.empty() && nsIsDbOnly(db)); const bool isRead = (_mode == MODE_S || _mode == MODE_IS); _lockState->lockGlobal(isRead ? MODE_IS : MODE_IX); if (supportsDocLocking() || enableCollectionLocking) { _lockState->lock(_id, _mode); } else { _lockState->lock(_id, isRead ? MODE_S : MODE_X); } }
StatusWith<OpTimePair<DatabaseType>> CatalogManagerReplicaSet::getDatabase( OperationContext* txn, const std::string& dbName) { invariant(nsIsDbOnly(dbName)); // The two databases that are hosted on the config server are config and admin if (dbName == "config" || dbName == "admin") { DatabaseType dbt; dbt.setName(dbName); dbt.setSharded(false); dbt.setPrimary("config"); return OpTimePair<DatabaseType>(dbt); } const auto configShard = grid.shardRegistry()->getShard(txn, "config"); const auto readHost = configShard->getTargeter()->findHost(kConfigReadSelector); if (!readHost.isOK()) { return readHost.getStatus(); } auto findStatus = _exhaustiveFindOnConfig(readHost.getValue(), NamespaceString(DatabaseType::ConfigNS), BSON(DatabaseType::name(dbName)), BSONObj(), 1); if (!findStatus.isOK()) { return findStatus.getStatus(); } const auto& docsWithOpTime = findStatus.getValue(); if (docsWithOpTime.value.empty()) { return {ErrorCodes::DatabaseNotFound, stream() << "database " << dbName << " not found"}; } invariant(docsWithOpTime.value.size() == 1); auto parseStatus = DatabaseType::fromBSON(docsWithOpTime.value.front()); if (!parseStatus.isOK()) { return parseStatus.getStatus(); } return OpTimePair<DatabaseType>(parseStatus.getValue(), docsWithOpTime.opTime); }
void _sleepInLock(mongo::OperationContext* opCtx, long long millis, LockMode mode, const StringData& ns) { if (ns.empty()) { Lock::GlobalLock lk(opCtx, mode, Date_t::max(), Lock::InterruptBehavior::kThrow); opCtx->sleepFor(Milliseconds(millis)); } else if (nsIsDbOnly(ns)) { uassert(50961, "lockTarget is not a valid namespace", NamespaceString::validDBName(ns)); Lock::DBLock lk(opCtx, ns, mode, Date_t::max()); opCtx->sleepFor(Milliseconds(millis)); } else { uassert(50962, "lockTarget is not a valid namespace", NamespaceString::validCollectionComponent(ns)); Lock::CollectionLock lk(opCtx, NamespaceString(ns), mode, Date_t::max()); opCtx->sleepFor(Milliseconds(millis)); } }