summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/catalog/database.h3
-rw-r--r--src/mongo/db/catalog/database_holder.cpp17
-rw-r--r--src/mongo/db/catalog/database_holder.h5
-rw-r--r--src/mongo/db/client.cpp23
-rw-r--r--src/mongo/db/client.h11
-rw-r--r--src/mongo/db/commands/mr.cpp2
-rw-r--r--src/mongo/db/db.cpp2
-rw-r--r--src/mongo/db/dbcommands.cpp2
-rw-r--r--src/mongo/db/instance.cpp17
-rw-r--r--src/mongo/db/pdfile.cpp2
-rw-r--r--src/mongo/db/repair_database.cpp6
-rw-r--r--src/mongo/dbtests/counttests.cpp30
-rw-r--r--src/mongo/dbtests/documentsourcetests.cpp30
13 files changed, 29 insertions, 121 deletions
diff --git a/src/mongo/db/catalog/database.h b/src/mongo/db/catalog/database.h
index c3d12a3dd18..c8a40213baa 100644
--- a/src/mongo/db/catalog/database.h
+++ b/src/mongo/db/catalog/database.h
@@ -66,7 +66,8 @@ namespace mongo {
/* you must use this to close - there is essential code in this method that is not in the ~Database destructor.
thus the destructor is private. this could be cleaned up one day...
*/
- static void closeDatabase( const std::string& db, const std::string& path );
+ static void closeDatabase(
+ OperationContext* txn, const std::string& db, const std::string& path);
const std::string& name() const { return _name; }
const std::string& path() const { return _path; }
diff --git a/src/mongo/db/catalog/database_holder.cpp b/src/mongo/db/catalog/database_holder.cpp
index 67d9282a894..224e50451f6 100644
--- a/src/mongo/db/catalog/database_holder.cpp
+++ b/src/mongo/db/catalog/database_holder.cpp
@@ -95,9 +95,11 @@ namespace mongo {
return db;
}
- bool DatabaseHolder::closeAll( const string& path , BSONObjBuilder& result , bool force ) {
+ bool DatabaseHolder::closeAll(
+ OperationContext* txn, const string& path, BSONObjBuilder& result, bool force) {
log() << "DatabaseHolder::closeAll path:" << path << endl;
- verify( Lock::isW() );
+ invariant(txn->lockState()->isW());
+
getDur().commitNow(); // bad things happen if we close a DB with outstanding writes
map<string,Database*>& m = _paths[path];
@@ -109,8 +111,6 @@ namespace mongo {
dbs.insert( i->first );
}
- currentClient.get()->getContext()->_clear();
-
BSONObjBuilder bb( result.subarrayStart( "dbs" ) );
int n = 0;
int nNotClosed = 0;
@@ -119,11 +119,14 @@ namespace mongo {
LOG(2) << "DatabaseHolder::closeAll path:" << path << " name:" << name << endl;
Client::Context ctx( name , path );
if( !force && BackgroundOperation::inProgForDb(name) ) {
- log() << "WARNING: can't close database " << name << " because a bg job is in progress - try killOp command" << endl;
+ log() << "WARNING: can't close database "
+ << name
+ << " because a bg job is in progress - try killOp command"
+ << endl;
nNotClosed++;
}
else {
- Database::closeDatabase( name.c_str() , path );
+ Database::closeDatabase(txn, name.c_str(), path);
bb.append( bb.numStr( n++ ) , name );
}
}
@@ -134,6 +137,4 @@ namespace mongo {
return true;
}
-
-
}
diff --git a/src/mongo/db/catalog/database_holder.h b/src/mongo/db/catalog/database_holder.h
index 751215518c6..007ed7a3871 100644
--- a/src/mongo/db/catalog/database_holder.h
+++ b/src/mongo/db/catalog/database_holder.h
@@ -95,7 +95,10 @@ namespace mongo {
}
/** @param force - force close even if something underway - use at shutdown */
- bool closeAll( const std::string& path , BSONObjBuilder& result, bool force );
+ bool closeAll(OperationContext* txn,
+ const std::string& path,
+ BSONObjBuilder& result,
+ bool force);
// "info" as this is informational only could change on you if you are not write locked
int sizeInfo() const { return _size; }
diff --git a/src/mongo/db/client.cpp b/src/mongo/db/client.cpp
index 9aa0f93ff81..14f38e4fd31 100644
--- a/src/mongo/db/client.cpp
+++ b/src/mongo/db/client.cpp
@@ -96,7 +96,6 @@ namespace mongo {
Client::Client(const string& desc, AbstractMessagingPort *p) :
ClientBasic(p),
- _context(0),
_shutdown(false),
_desc(desc),
_god(0),
@@ -165,7 +164,6 @@ namespace mongo {
BSONObj CachedBSONObjBase::_tooBig = fromjson("{\"$msg\":\"query not recording (too large)\"}");
Client::Context::Context(const std::string& ns , Database * db) :
_client( currentClient.get() ),
- _oldContext( _client->_context ),
_path(storageGlobalParams.dbpath), // is this right? could be a different db?
// may need a dassert for this
_justCreated(false),
@@ -173,12 +171,11 @@ namespace mongo {
_ns( ns ),
_db(db)
{
- _client->_context = this;
+
}
Client::Context::Context(const string& ns, const std::string& path, bool doVersion) :
_client( currentClient.get() ),
- _oldContext( _client->_context ),
_path( path ),
_justCreated(false), // set for real in finishInit
_doVersion(doVersion),
@@ -260,7 +257,6 @@ namespace mongo {
// invoked from ReadContext
Client::Context::Context(const string& path, const string& ns, Database *db, bool doVersion) :
_client( currentClient.get() ),
- _oldContext( _client->_context ),
_path( path ),
_justCreated(false),
_doVersion( doVersion ),
@@ -269,7 +265,6 @@ namespace mongo {
{
verify(_db);
if (_doVersion) checkNotStale();
- _client->_context = this;
_client->_curOp->enter( this );
}
@@ -280,28 +275,12 @@ namespace mongo {
if( _doVersion ) checkNotStale();
- _client->_context = this;
_client->_curOp->enter( this );
}
Client::Context::~Context() {
DEV verify( _client == currentClient.get() );
_client->_curOp->recordGlobalTime( _timer.micros() );
- _client->_context = _oldContext; // note: _oldContext may be null
- }
-
- bool Client::Context::inDB( const string& db , const string& path ) const {
- if ( _path != path )
- return false;
-
- if ( db == _ns )
- return true;
-
- string::size_type idx = _ns.find( db );
- if ( idx != 0 )
- return false;
-
- return _ns[db.size()] == '.';
}
void Client::appendLastOp( BSONObjBuilder& b ) const {
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h
index 852b2c0567f..6775bf579e7 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -92,7 +92,6 @@ namespace mongo {
std::string clientAddress(bool includePort=false) const;
CurOp* curop() const { return _curOp; }
- Context* getContext() const { return _context; }
const StringData desc() const { return _desc; }
void setLastOp( OpTime op ) { _lastOp = op; }
OpTime getLastOp() const { return _lastOp; }
@@ -127,7 +126,6 @@ namespace mongo {
ConnectionId _connectionId; // > 0 for things "conn", 0 otherwise
std::string _threadId; // "" on non support systems
CurOp * _curOp;
- Context * _context;
bool _shutdown; // to track if Client::shutdown() gets called
std::string _desc;
bool _god;
@@ -184,14 +182,6 @@ namespace mongo {
/** @return if the db was created by this Context */
bool justCreated() const { return _justCreated; }
- /** @return true iff the current Context is using db/path */
- bool inDB(const std::string& db, const std::string& path=storageGlobalParams.dbpath) const;
-
- void _clear() { // this is sort of an "early destruct" indication, _ns can never be uncleared
- const_cast<std::string&>(_ns).clear();
- _db = 0;
- }
-
/** call before unlocking, so clear any non-thread safe state
* _db gets restored on the relock
*/
@@ -207,7 +197,6 @@ namespace mongo {
void checkNsAccess( bool doauth );
void checkNsAccess( bool doauth, int lockState );
Client * const _client;
- Context * const _oldContext;
const std::string _path;
bool _justCreated;
bool _doVersion;
diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp
index 49e021e2e67..04e80d043df 100644
--- a/src/mongo/db/commands/mr.cpp
+++ b/src/mongo/db/commands/mr.cpp
@@ -1105,7 +1105,7 @@ namespace mongo {
// Make sure no DB read locks are held, because we might try to acquire write lock and
// upgrade is not supported.
//
- dassert(!cc().lockState().hasAnyReadLock());
+ dassert(!_txn->lockState()->hasAnyReadLock());
if (_jsMode) {
// try to reduce if it is beneficial
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index 654ad85c7d6..dc9999eeedc 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -452,7 +452,7 @@ namespace mongo {
warning() << "Internal error while reading collection " << systemIndexes;
}
- Database::closeDatabase(dbName.c_str(), storageGlobalParams.dbpath);
+ Database::closeDatabase(&txn, dbName.c_str(), storageGlobalParams.dbpath);
}
}
diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp
index 0db0dc827ff..e44909094bf 100644
--- a/src/mongo/db/dbcommands.cpp
+++ b/src/mongo/db/dbcommands.cpp
@@ -743,7 +743,7 @@ namespace mongo {
Client::Context ctx(dbname);
try {
- return dbHolder().closeAll(storageGlobalParams.dbpath, result, false);
+ return dbHolder().closeAll(txn, storageGlobalParams.dbpath, result, false);
}
catch(DBException&) {
throw;
diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp
index 7ae5dc045d2..cb29a9476d7 100644
--- a/src/mongo/db/instance.cpp
+++ b/src/mongo/db/instance.cpp
@@ -541,17 +541,13 @@ namespace mongo {
}
- /* db - database name
- path - db directory
- */
- /*static*/ void Database::closeDatabase( const string& db, const string& path ) {
- verify( Lock::isW() );
+ /*static*/
+ void Database::closeDatabase(OperationContext* txn, const string& db, const string& path) {
+ // XXX? - Do we need to close database under global lock or just DB-lock is sufficient ?
+ invariant(txn->lockState()->isW());
- Client::Context * ctx = cc().getContext();
- verify( ctx );
- verify( ctx->inDB( db , path ) );
- Database *database = ctx->db();
- verify( database->name() == db );
+ Database* database = dbHolder().get(db, path);
+ invariant(database != NULL);
repl::oplogCheckCloseDatabase(database); // oplog caches some things, dirty its caches
@@ -564,7 +560,6 @@ namespace mongo {
prefix += '.';
dbHolder().erase(db, path);
- ctx->_clear();
delete database; // closes files
}
diff --git a/src/mongo/db/pdfile.cpp b/src/mongo/db/pdfile.cpp
index 9d30c69ab45..741affbe6c3 100644
--- a/src/mongo/db/pdfile.cpp
+++ b/src/mongo/db/pdfile.cpp
@@ -173,7 +173,7 @@ namespace mongo {
txn->recoveryUnit()->syncDataAndTruncateJournal();
- Database::closeDatabase( name, db->path() );
+ Database::closeDatabase(txn, name, db->path());
db = 0; // d is now deleted
_deleteDataFiles( name );
diff --git a/src/mongo/db/repair_database.cpp b/src/mongo/db/repair_database.cpp
index 23f617877f2..6e7fec2a020 100644
--- a/src/mongo/db/repair_database.cpp
+++ b/src/mongo/db/repair_database.cpp
@@ -249,7 +249,7 @@ namespace mongo {
MongoFile::flushAll(true); // need both in case journaling is disabled
{
Client::Context tempContext( _dbName, _pathString );
- Database::closeDatabase( _dbName, _pathString );
+ Database::closeDatabase(_txn, _dbName, _pathString);
}
MONGO_ASSERT_ON_EXCEPTION( boost::filesystem::remove_all( _path ) );
}
@@ -433,7 +433,7 @@ namespace mongo {
txn->checkForInterrupt(false);
Client::Context tempContext( dbName, reservedPathString );
- Database::closeDatabase( dbName, reservedPathString );
+ Database::closeDatabase(txn, dbName, reservedPathString);
}
// at this point if we abort, we don't want to delete new files
@@ -443,7 +443,7 @@ namespace mongo {
repairFileDeleter->success();
Client::Context ctx( dbName );
- Database::closeDatabase(dbName, storageGlobalParams.dbpath);
+ Database::closeDatabase(txn, dbName, storageGlobalParams.dbpath);
if ( backupOriginalFiles ) {
_renameForBackup( dbName, reservedPath );
diff --git a/src/mongo/dbtests/counttests.cpp b/src/mongo/dbtests/counttests.cpp
index 7ece0d6e0ee..12c5907cb89 100644
--- a/src/mongo/dbtests/counttests.cpp
+++ b/src/mongo/dbtests/counttests.cpp
@@ -190,36 +190,6 @@ namespace CountTests {
mutable boost::condition _condition;
};
- /** A writer client will be registered for the lifetime of an object of this class. */
- class WriterClientScope {
- public:
- WriterClientScope() :
- _state( Initial ),
- _dummyWriter( stdx::bind( &WriterClientScope::runDummyWriter, this ) ) {
- _state.await( Ready );
- }
- ~WriterClientScope() {
- // Terminate the writer thread even on exception.
- _state.set( Finished );
- DESTRUCTOR_GUARD( _dummyWriter.join() );
- }
- private:
- enum State {
- Initial,
- Ready,
- Finished
- };
- void runDummyWriter() {
- Client::initThread( "dummy writer" );
- scoped_ptr<Acquiring> a( new Acquiring( 0 , cc().lockState() ) );
- _state.set( Ready );
- _state.await( Finished );
- a.reset(0);
- cc().shutdown();
- }
- PendingValue _state;
- boost::thread _dummyWriter;
- };
class All : public Suite {
public:
diff --git a/src/mongo/dbtests/documentsourcetests.cpp b/src/mongo/dbtests/documentsourcetests.cpp
index 58b0f957906..6972e8d7262 100644
--- a/src/mongo/dbtests/documentsourcetests.cpp
+++ b/src/mongo/dbtests/documentsourcetests.cpp
@@ -295,36 +295,6 @@ namespace DocumentSourceTests {
mutable boost::condition _condition;
};
- /** A writer client will be registered for the lifetime of an object of this class. */
- class WriterClientScope {
- public:
- WriterClientScope() :
- _state( Initial ),
- _dummyWriter( stdx::bind( &WriterClientScope::runDummyWriter, this ) ) {
- _state.await( Ready );
- }
- ~WriterClientScope() {
- // Terminate the writer thread even on exception.
- _state.set( Finished );
- DESTRUCTOR_GUARD( _dummyWriter.join() );
- }
- private:
- enum State {
- Initial,
- Ready,
- Finished
- };
- void runDummyWriter() {
- Client::initThread( "dummy writer" );
- scoped_ptr<Acquiring> a( new Acquiring( 0 , cc().lockState() ) );
- _state.set( Ready );
- _state.await( Finished );
- a.reset(0);
- cc().shutdown();
- }
- PendingValue _state;
- boost::thread _dummyWriter;
- };
/** Test coalescing a limit into a cursor */
class LimitCoalesce : public Base {