summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-12-09 13:45:33 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-12-10 16:34:53 -0500
commit314f6a94d1c4993da47b00427ad2e9694653dc18 (patch)
tree6b18e6247b823a81a683f57523c5296b48ebdf6c
parentbf834456c3e5a02fbe6fed340563a3c5fa548e4c (diff)
downloadmongo-314f6a94d1c4993da47b00427ad2e9694653dc18.tar.gz
SERVER-16429 Add ScopedTransactions to places which were missing it
-rw-r--r--src/mongo/db/auth/auth_index_d.cpp1
-rw-r--r--src/mongo/db/commands/dbhash.cpp1
-rw-r--r--src/mongo/db/commands/list_collections.cpp1
-rw-r--r--src/mongo/db/commands/write_commands/batch_executor.cpp5
-rw-r--r--src/mongo/db/commands/write_commands/write_commands.cpp2
-rw-r--r--src/mongo/db/concurrency/d_concurrency.cpp28
-rw-r--r--src/mongo/db/concurrency/d_concurrency.h19
-rw-r--r--src/mongo/db/concurrency/d_concurrency_test.cpp6
-rw-r--r--src/mongo/db/dbcommands.cpp1
-rw-r--r--src/mongo/db/index_rebuilder.cpp2
-rw-r--r--src/mongo/db/instance.cpp5
-rw-r--r--src/mongo/db/query/find.cpp1
-rw-r--r--src/mongo/db/repl/rs_initialsync.cpp1
-rw-r--r--src/mongo/db/ttl.cpp5
-rw-r--r--src/mongo/dbtests/counttests.cpp8
-rw-r--r--src/mongo/dbtests/dbhelper_tests.cpp9
-rw-r--r--src/mongo/dbtests/oplogstarttests.cpp5
-rw-r--r--src/mongo/dbtests/pdfiletests.cpp7
-rw-r--r--src/mongo/dbtests/query_stage_count.cpp12
-rw-r--r--src/mongo/dbtests/query_stage_ixscan.cpp16
-rw-r--r--src/mongo/dbtests/querytests.cpp38
-rw-r--r--src/mongo/dbtests/threadedtests.cpp100
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();