diff options
22 files changed, 165 insertions, 108 deletions
diff --git a/src/mongo/db/auth/auth_index_d.cpp b/src/mongo/db/auth/auth_index_d.cpp index 410a6e24de6..8b38dd099c3 100644 --- a/src/mongo/db/auth/auth_index_d.cpp +++ b/src/mongo/db/auth/auth_index_d.cpp @@ -78,6 +78,7 @@ namespace { const NamespaceString systemUsers = AuthorizationManager::usersCollectionNamespace; // Make sure the old unique index from v2.4 on system.users doesn't exist. + ScopedTransaction scopedXact(txn, MODE_IX); AutoGetDb autoDb(txn, systemUsers.db(), MODE_X); if (!autoDb.getDb()) { return Status::OK(); diff --git a/src/mongo/db/commands/dbhash.cpp b/src/mongo/db/commands/dbhash.cpp index 5235c409cc1..dfec4b07e64 100644 --- a/src/mongo/db/commands/dbhash.cpp +++ b/src/mongo/db/commands/dbhash.cpp @@ -151,6 +151,7 @@ namespace mongo { // We lock the entire database in S-mode in order to ensure that the contents will not // change for the snapshot. + ScopedTransaction scopedXact(txn, MODE_IS); AutoGetDb autoDb(txn, ns, MODE_S); Database* db = autoDb.getDb(); if (db) { diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp index c9dd45a3545..874c1b7e555 100644 --- a/src/mongo/db/commands/list_collections.cpp +++ b/src/mongo/db/commands/list_collections.cpp @@ -67,6 +67,7 @@ namespace mongo { BSONObjBuilder& result, bool /*fromRepl*/) { + ScopedTransaction scopedXact(txn, MODE_IS); AutoGetDb autoDb(txn, dbname, MODE_S); const Database* d = autoDb.getDb(); diff --git a/src/mongo/db/commands/write_commands/batch_executor.cpp b/src/mongo/db/commands/write_commands/batch_executor.cpp index f91a2106461..1be8e88f502 100644 --- a/src/mongo/db/commands/write_commands/batch_executor.cpp +++ b/src/mongo/db/commands/write_commands/batch_executor.cpp @@ -1353,8 +1353,11 @@ namespace mongo { return; } + ScopedTransaction scopedXact(txn, MODE_IX); AutoGetDb autoDb(txn, nss.db(), MODE_IX); - if (!autoDb.getDb()) break; + if (!autoDb.getDb()) { + break; + } Lock::CollectionLock collLock(txn->lockState(), nss.ns(), MODE_IX); diff --git a/src/mongo/db/commands/write_commands/write_commands.cpp b/src/mongo/db/commands/write_commands/write_commands.cpp index d1e777ffb6c..a462ecd87e9 100644 --- a/src/mongo/db/commands/write_commands/write_commands.cpp +++ b/src/mongo/db/commands/write_commands/write_commands.cpp @@ -187,6 +187,8 @@ namespace mongo { "explained write batches must be of size 1" ); } + ScopedTransaction scopedXact(txn, MODE_IX); + // Get a reference to the singleton batch item (it's the 0th item in the batch). BatchItemRef batchItem( &request, 0 ); diff --git a/src/mongo/db/concurrency/d_concurrency.cpp b/src/mongo/db/concurrency/d_concurrency.cpp index fad12d19f15..38140ccfc68 100644 --- a/src/mongo/db/concurrency/d_concurrency.cpp +++ b/src/mongo/db/concurrency/d_concurrency.cpp @@ -100,6 +100,7 @@ namespace mongo { } } + Lock::GlobalWrite::GlobalWrite(Locker* lockState, unsigned timeoutms) : ScopedLock(lockState) { @@ -116,6 +117,7 @@ namespace mongo { _lockState->unlockAll(); } + Lock::GlobalRead::GlobalRead(Locker* lockState, unsigned timeoutms) : ScopedLock(lockState) { @@ -129,20 +131,15 @@ namespace mongo { _lockState->unlockAll(); } + 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)); - lockDB(); - } - Lock::DBLock::~DBLock() { - unlockDB(); - } - - void Lock::DBLock::lockDB() { const bool isRead = (_mode == MODE_S || _mode == MODE_IS); _lockState->lockGlobal(isRead ? MODE_IS : MODE_IX); @@ -154,6 +151,12 @@ namespace mongo { } } + Lock::DBLock::~DBLock() { + _lockState->unlock(_id); + + _lockState->unlockAll(); + } + void Lock::DBLock::relockWithMode(const LockMode newMode) { const bool wasRead = (_mode == MODE_S || _mode == MODE_IS); const bool isRead = (newMode == MODE_S || newMode == MODE_IS); @@ -175,11 +178,6 @@ namespace mongo { } } - void Lock::DBLock::unlockDB() { - _lockState->unlock(_id); - - _lockState->unlockAll(); - } Lock::CollectionLock::CollectionLock(Locker* lockState, const StringData& ns, @@ -213,9 +211,9 @@ namespace mongo { if (supportsDocLocking() || enableCollectionLocking) { _lockState->lock(_id, mode); } - } + Lock::ResourceLock::ResourceLock(Locker* lockState, ResourceId rid, LockMode mode) : _rid(rid), _lockState(lockState) { @@ -226,8 +224,6 @@ namespace mongo { _lockState->unlock(_rid); } - Lock::DBRead::DBRead(Locker* lockState, const StringData& dbOrNs) : - DBLock(lockState, nsToDatabaseSubstring(dbOrNs), MODE_S) { } writelocktry::writelocktry(Locker* lockState, int tryms) : _got( false ), @@ -246,6 +242,7 @@ namespace mongo { } + // note: the 'already' concept here might be a bad idea as a temprelease wouldn't notice it is nested then readlocktry::readlocktry(Locker* lockState, int tryms) : _got( false ), @@ -263,5 +260,4 @@ namespace mongo { readlocktry::~readlocktry() { } - } diff --git a/src/mongo/db/concurrency/d_concurrency.h b/src/mongo/db/concurrency/d_concurrency.h index 10868829eaa..09859c1caff 100644 --- a/src/mongo/db/concurrency/d_concurrency.h +++ b/src/mongo/db/concurrency/d_concurrency.h @@ -156,10 +156,9 @@ namespace mongo { void relockWithMode(const LockMode newMode); private: - void lockDB(); - void unlockDB(); - const ResourceId _id; + Locker* const _lockState; + LockMode _mode; // may be changed through relockWithMode }; @@ -185,6 +184,7 @@ namespace mongo { ~CollectionLock(); void relockWithMode( const LockMode mode, Lock::DBLock& dblock ); + private: const ResourceId _id; Locker* const _lockState; @@ -208,19 +208,6 @@ namespace mongo { const ResourceId _rid; Locker* const _lockState; }; - - - /** - * Shared database lock -- DEPRECATED, please transition to DBLock and collection locks - * - * Allows concurrent read access to the given database, blocking any writers. - * Allows further (recursive) acquisision of database locks for this database in shared - * or intent-shared mode. Also acquires global lock in intent-shared (IS) mode. - */ - class DBRead : public DBLock { - public: - DBRead(Locker* lockState, const StringData& dbOrNs); - }; }; class DBTryLockTimeoutException : public std::exception { diff --git a/src/mongo/db/concurrency/d_concurrency_test.cpp b/src/mongo/db/concurrency/d_concurrency_test.cpp index 64615f79bcb..cdc28b34d25 100644 --- a/src/mongo/db/concurrency/d_concurrency_test.cpp +++ b/src/mongo/db/concurrency/d_concurrency_test.cpp @@ -152,10 +152,10 @@ namespace mongo { ASSERT(ls.isW()); } - TEST(DConcurrency, DBReadTakesS) { + TEST(DConcurrency, DBLockTakesS) { MMAPV1LockerImpl ls(1); - Lock::DBRead dbRead(&ls, "db"); + Lock::DBLock dbRead(&ls, "db", MODE_S); const ResourceId resIdDb(RESOURCE_DATABASE, string("db")); ASSERT(ls.getLockMode(resIdDb) == MODE_S); @@ -183,7 +183,7 @@ namespace mongo { MMAPV1LockerImpl ls(1); Lock::DBLock r1(&ls, "db1", MODE_X); - Lock::DBRead r2(&ls, "db1"); + Lock::DBLock r2(&ls, "db1", MODE_S); ASSERT(ls.isWriteLocked("db1")); } diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index 915b5fff6db..d06ee746509 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -1140,6 +1140,7 @@ namespace mongo { // We lock the entire database in S-mode in order to ensure that the contents will not // change for the stats snapshot. This might be unnecessary and if it becomes a // performance issue, we can take IS lock and then lock collection-by-collection. + ScopedTransaction scopedXact(txn, MODE_IS); AutoGetDb autoDb(txn, ns, MODE_S); result.append("db", ns); diff --git a/src/mongo/db/index_rebuilder.cpp b/src/mongo/db/index_rebuilder.cpp index b23270e3afe..dcf311ded1b 100644 --- a/src/mongo/db/index_rebuilder.cpp +++ b/src/mongo/db/index_rebuilder.cpp @@ -156,6 +156,8 @@ namespace { for (std::vector<std::string>::const_iterator dbName = dbNames.begin(); dbName < dbNames.end(); ++dbName) { + + ScopedTransaction scopedXact(txn, MODE_IS); AutoGetDb autoDb(txn, *dbName, MODE_S); Database* db = autoDb.getDb(); diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp index 74ebd47def0..8ba0cfbe52e 100644 --- a/src/mongo/db/instance.cpp +++ b/src/mongo/db/instance.cpp @@ -685,8 +685,11 @@ namespace { ParsedDelete parsedDelete(txn, &request); uassertStatusOK(parsedDelete.parseRequest()); + ScopedTransaction scopedXact(txn, MODE_IX); AutoGetDb autoDb(txn, ns.db(), MODE_IX); - if (!autoDb.getDb()) break; + if (!autoDb.getDb()) { + break; + } Lock::CollectionLock colLock(txn->lockState(), ns.ns(), MODE_IX); Client::Context ctx(txn, ns); diff --git a/src/mongo/db/query/find.cpp b/src/mongo/db/query/find.cpp index ca704fe4b2e..90ff4673c78 100644 --- a/src/mongo/db/query/find.cpp +++ b/src/mongo/db/query/find.cpp @@ -589,6 +589,7 @@ namespace mongo { // Parse, canonicalize, plan, transcribe, and get a plan executor. PlanExecutor* rawExec = NULL; + ScopedTransaction scopedXact(txn, MODE_IS); AutoGetCollectionForRead ctx(txn, nss); const int dbProfilingLevel = (ctx.getDb() != NULL) ? ctx.getDb()->getProfilingLevel() : diff --git a/src/mongo/db/repl/rs_initialsync.cpp b/src/mongo/db/repl/rs_initialsync.cpp index 098a0e7c4e1..f0ff437740e 100644 --- a/src/mongo/db/repl/rs_initialsync.cpp +++ b/src/mongo/db/repl/rs_initialsync.cpp @@ -373,6 +373,7 @@ namespace { log() << "initial sync finishing up"; { + ScopedTransaction scopedXact(&txn, MODE_IX); AutoGetDb autodb(&txn, "local", MODE_X); OpTime lastOpTimeWritten(getGlobalReplicationCoordinator()->getMyLastOptime()); log() << "replSet set minValid=" << lastOpTimeWritten; diff --git a/src/mongo/db/ttl.cpp b/src/mongo/db/ttl.cpp index 9e1413ce973..8d0836b045e 100644 --- a/src/mongo/db/ttl.cpp +++ b/src/mongo/db/ttl.cpp @@ -209,9 +209,12 @@ namespace mongo { { const string ns = idx["ns"].String(); + ScopedTransaction scopedXact(txn, MODE_IX); AutoGetDb autoDb(txn, dbName, MODE_IX); Database* db = autoDb.getDb(); - if (!db) return false; + if (!db) { + return false; + } Lock::CollectionLock collLock( txn->lockState(), ns, MODE_IX ); diff --git a/src/mongo/dbtests/counttests.cpp b/src/mongo/dbtests/counttests.cpp index 2613c3b933c..a854ebc0110 100644 --- a/src/mongo/dbtests/counttests.cpp +++ b/src/mongo/dbtests/counttests.cpp @@ -43,10 +43,15 @@ namespace CountTests { class Base { public: - Base() : _lk(_txn.lockState(), nsToDatabaseSubstring(ns()), MODE_X), + Base() : _txn(), + _scopedXact(&_txn, MODE_IX), + _lk(_txn.lockState(), + nsToDatabaseSubstring(ns()), MODE_X), _context(&_txn, ns()), _client(&_txn) { + _database = _context.db(); + { WriteUnitOfWork wunit(&_txn); _collection = _database->getCollection( &_txn, ns() ); @@ -104,6 +109,7 @@ namespace CountTests { OperationContextImpl _txn; + ScopedTransaction _scopedXact; Lock::DBLock _lk; Client::Context _context; diff --git a/src/mongo/dbtests/dbhelper_tests.cpp b/src/mongo/dbtests/dbhelper_tests.cpp index 081d37108a1..aa30a6fa749 100644 --- a/src/mongo/dbtests/dbhelper_tests.cpp +++ b/src/mongo/dbtests/dbhelper_tests.cpp @@ -139,7 +139,8 @@ namespace mongo { long long estSizeBytes; { // search _id range (0, 10) - Lock::DBRead lk(txn.lockState(), ns); + ScopedTransaction transaction(&txn, MODE_IS); + Lock::DBLock lk(txn.lockState(), nsToDatabaseSubstring(ns), MODE_S); KeyRange range( ns, BSON( "_id" << 0 ), @@ -186,7 +187,8 @@ namespace mongo { long long numDocsFound; long long estSizeBytes; { - Lock::DBRead lk(txn.lockState(), ns); + ScopedTransaction transaction(&txn, MODE_IS); + Lock::DBLock lk(txn.lockState(), nsToDatabaseSubstring(ns), MODE_S); // search invalid index range KeyRange range( ns, @@ -231,7 +233,8 @@ namespace mongo { long long numDocsFound; long long estSizeBytes; { - Lock::DBRead lk(txn.lockState(), ns); + ScopedTransaction transaction(&txn, MODE_IS); + Lock::DBLock lk(txn.lockState(), nsToDatabaseSubstring(ns), MODE_S); KeyRange range( ns, BSON( "_id" << 0 ), diff --git a/src/mongo/dbtests/oplogstarttests.cpp b/src/mongo/dbtests/oplogstarttests.cpp index 52c5ee2a9ec..b84724ed853 100644 --- a/src/mongo/dbtests/oplogstarttests.cpp +++ b/src/mongo/dbtests/oplogstarttests.cpp @@ -37,7 +37,9 @@ namespace OplogStartTests { class Base { public: - Base() : _lk(_txn.lockState()), + Base() : _txn(), + _scopedXact(&_txn, MODE_X), + _lk(_txn.lockState()), _wunit(&_txn), _context(&_txn, ns()), _client(&_txn) { @@ -98,6 +100,7 @@ namespace OplogStartTests { private: // The order of these is important in order to ensure order of destruction OperationContextImpl _txn; + ScopedTransaction _scopedXact; Lock::GlobalWrite _lk; WriteUnitOfWork _wunit; Client::Context _context; diff --git a/src/mongo/dbtests/pdfiletests.cpp b/src/mongo/dbtests/pdfiletests.cpp index 0808a666b2d..9d2a0fb2078 100644 --- a/src/mongo/dbtests/pdfiletests.cpp +++ b/src/mongo/dbtests/pdfiletests.cpp @@ -29,7 +29,7 @@ * then also delete it in the license file. */ -#include "mongo/pch.h" +#include "mongo/platform/basic.h" #include "mongo/db/db.h" #include "mongo/db/json.h" @@ -43,8 +43,10 @@ namespace PdfileTests { namespace Insert { class Base { public: - Base() : _lk(_txn.lockState()), + Base() : _scopedXact(&_txn, MODE_X), + _lk(_txn.lockState()), _context(&_txn, ns()) { + } virtual ~Base() { @@ -64,6 +66,7 @@ namespace PdfileTests { } OperationContextImpl _txn; + ScopedTransaction _scopedXact; Lock::GlobalWrite _lk; Client::Context _context; }; diff --git a/src/mongo/dbtests/query_stage_count.cpp b/src/mongo/dbtests/query_stage_count.cpp index 4338880ec73..d8310f42934 100644 --- a/src/mongo/dbtests/query_stage_count.cpp +++ b/src/mongo/dbtests/query_stage_count.cpp @@ -47,10 +47,13 @@ namespace QueryStageCount { class CountStageTest { public: CountStageTest() - : _dbLock(_txn.lockState(), nsToDatabaseSubstring(ns()), MODE_X) - , _ctx(&_txn, ns()) - , _coll(NULL) - {} + : _txn(), + _scopedXact(&_txn, MODE_IX), + _dbLock(_txn.lockState(), nsToDatabaseSubstring(ns()), MODE_X), + _ctx(&_txn, ns()), + _coll(NULL) { + + } virtual ~CountStageTest() {} @@ -218,6 +221,7 @@ namespace QueryStageCount { protected: vector<RecordId> _locs; OperationContextImpl _txn; + ScopedTransaction _scopedXact; Lock::DBLock _dbLock; Client::Context _ctx; Collection* _coll; diff --git a/src/mongo/dbtests/query_stage_ixscan.cpp b/src/mongo/dbtests/query_stage_ixscan.cpp index 49388655340..a9508c70d2c 100644 --- a/src/mongo/dbtests/query_stage_ixscan.cpp +++ b/src/mongo/dbtests/query_stage_ixscan.cpp @@ -37,10 +37,14 @@ namespace QueryStageIxscan { class IndexScanTest { public: - IndexScanTest() : - _dbLock(_txn.lockState(), nsToDatabaseSubstring(ns()), MODE_X), - _ctx(&_txn, ns()), - _coll(NULL) { } + IndexScanTest() + : _txn(), + _scopedXact(&_txn, MODE_IX), + _dbLock(_txn.lockState(), nsToDatabaseSubstring(ns()), MODE_X), + _ctx(&_txn, ns()), + _coll(NULL) { + + } virtual ~IndexScanTest() { } @@ -84,11 +88,13 @@ namespace QueryStageIxscan { protected: OperationContextImpl _txn; - WorkingSet _ws; + ScopedTransaction _scopedXact; Lock::DBLock _dbLock; Client::Context _ctx; Collection* _coll; + + WorkingSet _ws; }; // SERVER-15958: Some IndexScanStats info must be initialized on construction of an IndexScan. diff --git a/src/mongo/dbtests/querytests.cpp b/src/mongo/dbtests/querytests.cpp index 8e47a13ad05..f0a9584782c 100644 --- a/src/mongo/dbtests/querytests.cpp +++ b/src/mongo/dbtests/querytests.cpp @@ -54,17 +54,11 @@ namespace mongo { namespace QueryTests { class Base { - protected: - OperationContextImpl _txn; - Lock::GlobalWrite _lk; - Client::Context _context; - - Database* _database; - Collection* _collection; - public: - Base() : _lk(_txn.lockState()), + Base() : _scopedXact(&_txn, MODE_X), + _lk(_txn.lockState()), _context(&_txn, ns()) { + { WriteUnitOfWork wunit(&_txn); _database = _context.db(); @@ -75,8 +69,10 @@ namespace QueryTests { _collection = _database->createCollection( &_txn, ns() ); wunit.commit(); } + addIndex( fromjson( "{\"a\":1}" ) ); } + ~Base() { try { WriteUnitOfWork wunit(&_txn); @@ -87,16 +83,20 @@ namespace QueryTests { FAIL( "Exception while cleaning up collection" ); } } + protected: static const char *ns() { return "unittests.querytests"; } + void addIndex( const BSONObj &key ) { Helpers::ensureIndex(&_txn, _collection, key, false, key.firstElementFieldName()); } + void insert( const char *s ) { insert( fromjson( s ) ); } + void insert( const BSONObj &o ) { WriteUnitOfWork wunit(&_txn); if ( o["_id"].eoo() ) { @@ -112,6 +112,15 @@ namespace QueryTests { } wunit.commit(); } + + + OperationContextImpl _txn; + ScopedTransaction _scopedXact; + Lock::GlobalWrite _lk; + Client::Context _context; + + Database* _database; + Collection* _collection; }; class FindOneOr : public Base { @@ -1441,13 +1450,16 @@ namespace QueryTests { class CollectionInternalBase : public CollectionBase { public: - CollectionInternalBase( const char *nsLeaf ) : - CollectionBase( nsLeaf ), - _lk(_txn.lockState(), "unittests", MODE_X), - _ctx(&_txn, ns()) { + CollectionInternalBase( const char *nsLeaf ) + : CollectionBase( nsLeaf ), + _scopedXact(&_txn, MODE_IX), + _lk(_txn.lockState(), "unittests", MODE_X), + _ctx(&_txn, ns()) { + } private: + ScopedTransaction _scopedXact; Lock::DBLock _lk; Client::Context _ctx; }; diff --git a/src/mongo/dbtests/threadedtests.cpp b/src/mongo/dbtests/threadedtests.cpp index 1eb135872b1..fe6e3945e53 100644 --- a/src/mongo/dbtests/threadedtests.cpp +++ b/src/mongo/dbtests/threadedtests.cpp @@ -37,6 +37,7 @@ #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/concurrency/lock_state.h" +#include "mongo/db/operation_context_impl.h" #include "mongo/dbtests/dbtests.h" #include "mongo/platform/atomic_word.h" #include "mongo/platform/bits.h" @@ -112,112 +113,129 @@ namespace ThreadedTests { virtual void subthread(int tnumber) { Client::initThread("mongomutextest"); - MMAPV1LockerImpl lockState(1); + OperationContextImpl txn; sleepmillis(0); for( int i = 0; i < N; i++ ) { int x = std::rand(); bool sometimes = (x % 15 == 0); if( i % 7 == 0 ) { - Lock::GlobalRead r(&lockState); // nested test - Lock::GlobalRead r2(&lockState); + Lock::GlobalRead r(txn.lockState()); // nested test + Lock::GlobalRead r2(txn.lockState()); } else if( i % 7 == 1 ) { - Lock::GlobalRead r(&lockState); - ASSERT(lockState.hasAnyReadLock()); + Lock::GlobalRead r(txn.lockState()); + ASSERT(txn.lockState()->hasAnyReadLock()); } else if( i % 7 == 4 && tnumber == 1 /*only one upgrader legal*/ ) { - Lock::GlobalWrite w(&lockState); - ASSERT( lockState.isW() ); + Lock::GlobalWrite w(txn.lockState()); + ASSERT( txn.lockState()->isW() ); if( i % 7 == 2 ) { - Lock::TempRelease t(&lockState); + Lock::TempRelease t(txn.lockState()); } } else if( i % 7 == 2 ) { - Lock::GlobalWrite w(&lockState); - ASSERT( lockState.isW() ); + Lock::GlobalWrite w(txn.lockState()); + ASSERT( txn.lockState()->isW() ); if( sometimes ) { - Lock::TempRelease t(&lockState); + Lock::TempRelease t(txn.lockState()); } } else if( i % 7 == 3 ) { - Lock::GlobalWrite w(&lockState); + Lock::GlobalWrite w(txn.lockState()); { - Lock::TempRelease t(&lockState); + Lock::TempRelease t(txn.lockState()); } - Lock::GlobalRead r(&lockState); - ASSERT( lockState.isW() ); + Lock::GlobalRead r(txn.lockState()); + ASSERT( txn.lockState()->isW() ); if( sometimes ) { - Lock::TempRelease t(&lockState); + Lock::TempRelease t(txn.lockState()); } } else if( i % 7 == 5 ) { { - Lock::DBRead r(&lockState, "foo"); + ScopedTransaction scopedXact(&txn, MODE_IS); + Lock::DBLock r(txn.lockState(), "foo", MODE_S); } { - Lock::DBRead r(&lockState, "bar"); + ScopedTransaction scopedXact(&txn, MODE_IS); + Lock::DBLock r(txn.lockState(), "bar", MODE_S); } } else if( i % 7 == 6 ) { if( i > N/2 ) { int q = i % 11; if( q == 0 ) { - Lock::DBRead r(&lockState, "foo"); - ASSERT(lockState.isDbLockedForMode("foo", MODE_S)); + ScopedTransaction scopedXact(&txn, MODE_IS); - Lock::DBRead r2(&lockState, "foo"); - ASSERT(lockState.isDbLockedForMode("foo", MODE_S)); + Lock::DBLock r(txn.lockState(), "foo", MODE_S); + ASSERT(txn.lockState()->isDbLockedForMode("foo", MODE_S)); - Lock::DBRead r3(&lockState, "local"); - ASSERT(lockState.isDbLockedForMode("foo", MODE_S)); - ASSERT(lockState.isDbLockedForMode("local", MODE_S)); + Lock::DBLock r2(txn.lockState(), "foo", MODE_S); + ASSERT(txn.lockState()->isDbLockedForMode("foo", MODE_S)); + + Lock::DBLock r3(txn.lockState(), "local", MODE_S); + ASSERT(txn.lockState()->isDbLockedForMode("foo", MODE_S)); + ASSERT(txn.lockState()->isDbLockedForMode("local", MODE_S)); } else if( q == 1 ) { // test locking local only -- with no preceding lock { - Lock::DBRead x(&lockState, "local"); + ScopedTransaction scopedXact(&txn, MODE_IS); + Lock::DBLock x(txn.lockState(), "local", MODE_S); } { - Lock::DBLock x(&lockState, "local", MODE_X); + ScopedTransaction scopedXact(&txn, MODE_IX); + Lock::DBLock x(txn.lockState(), "local", MODE_X); + // No actual writing here, so no WriteUnitOfWork if( sometimes ) { - Lock::TempRelease t(&lockState); + Lock::TempRelease t(txn.lockState()); } } } else if( q == 1 ) { { - Lock::DBRead x(&lockState, "admin"); + ScopedTransaction scopedXact(&txn, MODE_IS); + Lock::DBLock x(txn.lockState(), "admin", MODE_S); } { - Lock::DBLock x(&lockState, "admin", MODE_X); + ScopedTransaction scopedXact(&txn, MODE_IX); + Lock::DBLock x(txn.lockState(), "admin", MODE_X); } } else if( q == 3 ) { - Lock::DBLock x(&lockState, "foo", MODE_X); - Lock::DBRead y(&lockState, "admin"); + ScopedTransaction scopedXact(&txn, MODE_IX); + + Lock::DBLock x(txn.lockState(), "foo", MODE_X); + Lock::DBLock y(txn.lockState(), "admin", MODE_S); } else if( q == 4 ) { - Lock::DBRead x(&lockState, "foo2"); - Lock::DBRead y(&lockState, "admin"); + ScopedTransaction scopedXact(&txn, MODE_IS); + + Lock::DBLock x(txn.lockState(), "foo2", MODE_S); + Lock::DBLock y(txn.lockState(), "admin", MODE_S); } else { - Lock::DBLock w(&lockState, "foo", MODE_X); + ScopedTransaction scopedXact(&txn, MODE_IX); + + Lock::DBLock w(txn.lockState(), "foo", MODE_X); { - Lock::TempRelease t(&lockState); + Lock::TempRelease t(txn.lockState()); } - Lock::DBRead r2(&lockState, "foo"); - Lock::DBRead r3(&lockState, "local"); + Lock::DBLock r2(txn.lockState(), "foo", MODE_S); + Lock::DBLock r3(txn.lockState(), "local", MODE_S); } } else { - Lock::DBRead r(&lockState, "foo"); - Lock::DBRead r2(&lockState, "foo"); - Lock::DBRead r3(&lockState, "local"); + ScopedTransaction scopedXact(&txn, MODE_IS); + + Lock::DBLock r(txn.lockState(), "foo", MODE_S); + Lock::DBLock r2(txn.lockState(), "foo", MODE_S); + Lock::DBLock r3(txn.lockState(), "local", MODE_S); } } pm.hit(); |