diff options
author | Antonin Kral <a.kral@bobek.cz> | 2010-06-30 08:56:42 +0200 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2010-06-30 08:56:42 +0200 |
commit | 5c6a2219e6715bd7649c3fd28f58e6fb63d60a25 (patch) | |
tree | 1eda5f5ca9bd35190fe499a51119e855774b16c0 /db | |
parent | df7046adebaeb16716b5a2cebc6f34694f530caf (diff) | |
download | mongodb-5c6a2219e6715bd7649c3fd28f58e6fb63d60a25.tar.gz |
Imported Upstream version 1.4.4
Diffstat (limited to 'db')
-rw-r--r-- | db/concurrency.h | 57 | ||||
-rw-r--r-- | db/database.h | 17 | ||||
-rw-r--r-- | db/db.cpp | 24 | ||||
-rw-r--r-- | db/instance.cpp | 8 | ||||
-rw-r--r-- | db/pdfile.cpp | 9 | ||||
-rw-r--r-- | db/repl.cpp | 19 | ||||
-rw-r--r-- | db/stats/top.cpp | 2 | ||||
-rw-r--r-- | db/update.cpp | 2 | ||||
-rw-r--r-- | db/update.h | 12 |
9 files changed, 105 insertions, 45 deletions
diff --git a/db/concurrency.h b/db/concurrency.h index de8f242..e841d61 100644 --- a/db/concurrency.h +++ b/db/concurrency.h @@ -113,16 +113,26 @@ namespace mongo { bool atLeastReadLocked() { return _state.get() != 0; } void assertAtLeastReadLocked() { assert(atLeastReadLocked()); } - void lock() { + bool _checkWriteLockAlready(){ //DEV cout << "LOCK" << endl; DEV assert( haveClient() ); int s = _state.get(); if( s > 0 ) { _state.set(s+1); - return; + return true; } + massert( 10293 , (string)"internal error: locks are not upgradeable: " + sayClientState() , s == 0 ); + + return false; + } + + void lock() { + + if ( _checkWriteLockAlready() ) + return; + _state.set(1); curopWaitingForLock( 1 ); @@ -131,6 +141,26 @@ namespace mongo { _minfo.entered(); } + + bool lock_try() { + if ( _checkWriteLockAlready() ) + return true; + + curopWaitingForLock( 1 ); + + boost::system_time until = get_system_time(); + until += boost::posix_time::milliseconds(0); + bool got = _m.timed_lock( until ); + curopGotLock(); + + if ( got ){ + _minfo.entered(); + _state.set(1); + } + + return got; + } + void unlock() { //DEV cout << "UNLOCK" << endl; int s = _state.get(); @@ -227,12 +257,18 @@ namespace mongo { void lock() { #ifdef HAVE_READLOCK m.lock(); +#error this should be impossible? #else boost::detail::thread::lock_ops<boost::recursive_mutex>::lock(m); #endif _minfo.entered(); } + bool lock_try(){ + lock(); + return true; + } + void releaseEarly() { assertWriteLocked(); // aso must not be recursive, although we don't verify that in the old boost version assert( !_releasedEarly.get() ); @@ -326,6 +362,23 @@ namespace mongo { } bool _got; }; + + struct writelocktry { + writelocktry( const string&ns ){ + _got = dbMutex.lock_try(); + } + ~writelocktry() { + if ( _got ){ + dbunlocking_write(); + dbMutex.unlock(); + } + } + bool got(){ + return _got; + } + bool _got; + }; + struct atleastreadlock { atleastreadlock( const string& ns ){ diff --git a/db/database.h b/db/database.h index 868af0b..23bca7c 100644 --- a/db/database.h +++ b/db/database.h @@ -154,7 +154,7 @@ namespace mongo { return preallocateOnly ? 0 : p; } - MongoDataFile* addAFile( int sizeNeeded = 0, bool preallocateNextFile = false ) { + MongoDataFile* addAFile( int sizeNeeded, bool preallocateNextFile ) { int n = (int) files.size(); MongoDataFile *ret = getFile( n, sizeNeeded ); if ( preallocateNextFile ) @@ -168,12 +168,15 @@ namespace mongo { getFile( n, 0, true ); } - MongoDataFile* suitableFile( int sizeNeeded ) { + MongoDataFile* suitableFile( int sizeNeeded, bool preallocate ) { MongoDataFile* f = newestFile(); + if ( !f ) { + f = addAFile( sizeNeeded, preallocate ); + } for ( int i = 0; i < 8; i++ ) { if ( f->getHeader()->unusedLength >= sizeNeeded ) break; - f = addAFile( sizeNeeded ); + f = addAFile( sizeNeeded, preallocate ); if ( f->getHeader()->fileLength >= MongoDataFile::maxSize() ) // this is as big as they get so might as well stop break; } @@ -183,12 +186,16 @@ namespace mongo { Extent* allocExtent( const char *ns, int size, bool capped ) { Extent *e = DataFileMgr::allocFromFreeList( ns, size, capped ); if( e ) return e; - return suitableFile( size )->createExtent( ns, size, capped ); + return suitableFile( size, !capped )->createExtent( ns, size, capped ); } MongoDataFile* newestFile() { int n = (int) files.size(); - if ( n > 0 ) n--; + if ( n > 0 ) { + n--; + } else { + return 0; + } return getFile(n); } @@ -193,22 +193,22 @@ namespace mongo { LastError *le = new LastError(); lastError.reset(le); - MessagingPort& dbMsgPort = *connGrab; + auto_ptr<MessagingPort> dbMsgPort( connGrab ); connGrab = 0; Client& c = cc(); try { - c.getAuthenticationInfo()->isLocalHost = dbMsgPort.farEnd.isLocalHost(); + c.getAuthenticationInfo()->isLocalHost = dbMsgPort->farEnd.isLocalHost(); Message m; while ( 1 ) { m.reset(); - if ( !dbMsgPort.recv(m) ) { + if ( !dbMsgPort->recv(m) ) { if( !cmdLine.quiet ) - log() << "end connection " << dbMsgPort.farEnd.toString() << endl; - dbMsgPort.shutdown(); + log() << "end connection " << dbMsgPort->farEnd.toString() << endl; + dbMsgPort->shutdown(); break; } @@ -220,11 +220,11 @@ namespace mongo { lastError.startRequest( m , le ); DbResponse dbresponse; - if ( !assembleResponse( m, dbresponse, dbMsgPort.farEnd.sa ) ) { - out() << curTimeMillis() % 10000 << " end msg " << dbMsgPort.farEnd.toString() << endl; + if ( !assembleResponse( m, dbresponse, dbMsgPort->farEnd.sa ) ) { + out() << curTimeMillis() % 10000 << " end msg " << dbMsgPort->farEnd.toString() << endl; /* todo: we may not wish to allow this, even on localhost: very low priv accounts could stop us. */ - if ( dbMsgPort.farEnd.isLocalHost() ) { - dbMsgPort.shutdown(); + if ( dbMsgPort->farEnd.isLocalHost() ) { + dbMsgPort->shutdown(); sleepmillis(50); problem() << "exiting end msg" << endl; dbexit(EXIT_CLEAN); @@ -235,17 +235,17 @@ namespace mongo { } if ( dbresponse.response ) - dbMsgPort.reply(m, *dbresponse.response, dbresponse.responseTo); + dbMsgPort->reply(m, *dbresponse.response, dbresponse.responseTo); } } catch ( AssertionException& ) { problem() << "AssertionException in connThread, closing client connection" << endl; - dbMsgPort.shutdown(); + dbMsgPort->shutdown(); } catch ( SocketException& ) { problem() << "SocketException in connThread, closing client connection" << endl; - dbMsgPort.shutdown(); + dbMsgPort->shutdown(); } catch ( const ClockSkewException & ) { exitCleanly( EXIT_CLOCK_SKEW ); diff --git a/db/instance.cpp b/db/instance.cpp index 909911e..d8a76cb 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -96,11 +96,13 @@ namespace mongo { scoped_lock bl(Client::clientsMutex); for( set<Client*>::iterator i = Client::clients.begin(); i != Client::clients.end(); i++ ) { Client *c = *i; + assert( c ); if ( c == &me ) continue; - CurOp& co = *(c->curop()); - if( all || co.active() ) - vals.push_back( co.infoNoauth() ); + CurOp* co = c->curop(); + assert( co ); + if( all || co->active() ) + vals.push_back( co->infoNoauth() ); } } b.append("inprog", vals); diff --git a/db/pdfile.cpp b/db/pdfile.cpp index 80ae649..95bdb17 100644 --- a/db/pdfile.cpp +++ b/db/pdfile.cpp @@ -197,7 +197,7 @@ namespace mongo { // $nExtents is just for testing - always allocate new extents // rather than reuse existing extents so we have some predictibility // in the extent size used by our tests - database->suitableFile( (int) size )->createExtent( ns, (int) size, newCapped ); + database->suitableFile( (int) size, false )->createExtent( ns, (int) size, newCapped ); } } else { while ( size > 0 ) { @@ -206,11 +206,6 @@ namespace mongo { Extent *e = database->allocExtent( ns, desiredExtentSize, newCapped ); size -= e->length; } - if ( !newCapped ) { - // check if it's time to preallocate a new file, and if so queue that job for a bg thread - // safe to call this multiple times - the implementation will only preallocate one file - database->preallocateAFile(); - } } NamespaceDetails *d = nsdetails(ns); @@ -1537,7 +1532,9 @@ namespace mongo { assumes ns is capped and no indexes */ Record* DataFileMgr::fast_oplog_insert(NamespaceDetails *d, const char *ns, int len) { + assert( d ); RARELY assert( d == nsdetails(ns) ); + DEV assert( d == nsdetails(ns) ); DiskLoc extentLoc; int lenWHdr = len + Record::HeaderSize; diff --git a/db/repl.cpp b/db/repl.cpp index a0ac16e..efb078b 100644 --- a/db/repl.cpp +++ b/db/repl.cpp @@ -1720,22 +1720,21 @@ namespace mongo { sleepsecs(4); Client::initThread("replmaster"); while( 1 ) { - { - dblock lk; - cc().getAuthenticationInfo()->authorize("admin"); - } sleepsecs(10); /* write a keep-alive like entry to the log. this will make things like printReplicationStatus() and printSlaveReplicationStatus() stay up-to-date even when things are idle. */ { - writelock lk(""); - try { - logKeepalive(); - } - catch(...) { - log() << "caught exception in replMasterThread()" << endl; + writelocktry lk(""); + if ( lk.got() ){ + cc().getAuthenticationInfo()->authorize("admin"); + try { + logKeepalive(); + } + catch(...) { + log() << "caught exception in replMasterThread()" << endl; + } } } } diff --git a/db/stats/top.cpp b/db/stats/top.cpp index 0f27943..462bfe6 100644 --- a/db/stats/top.cpp +++ b/db/stats/top.cpp @@ -99,7 +99,7 @@ namespace mongo { case opReply: case dbMsg: case dbKillCursors: - log() << "unexpected op in Top::record: " << op << endl; + //log() << "unexpected op in Top::record: " << op << endl; break; default: log() << "unknown op in Top::record: " << op << endl; diff --git a/db/update.cpp b/db/update.cpp index 6b9df9c..6dcfc78 100644 --- a/db/update.cpp +++ b/db/update.cpp @@ -67,7 +67,7 @@ namespace mongo { ms.incint = elt.numberInt() + in.numberInt(); } - ms.appendIncValue( bb ); + ms.appendIncValue( bb , false ); } template< class Builder > diff --git a/db/update.h b/db/update.h index 3c4daab..bfec7cd 100644 --- a/db/update.h +++ b/db/update.h @@ -413,7 +413,7 @@ namespace mongo { void appendForOpLog( BSONObjBuilder& b ) const { if ( incType ){ BSONObjBuilder bb( b.subobjStart( "$set" ) ); - appendIncValue( bb ); + appendIncValue( bb , true ); bb.done(); return; } @@ -434,14 +434,16 @@ namespace mongo { } template< class Builder > - void appendIncValue( Builder& b ) const { + void appendIncValue( Builder& b , bool useFullName ) const { + const char * n = useFullName ? m->fieldName : m->shortFieldName; + switch ( incType ){ case NumberDouble: - b.append( m->shortFieldName , incdouble ); break; + b.append( n , incdouble ); break; case NumberLong: - b.append( m->shortFieldName , inclong ); break; + b.append( n , inclong ); break; case NumberInt: - b.append( m->shortFieldName , incint ); break; + b.append( n , incint ); break; default: assert(0); } |