summaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
authorAntonin Kral <a.kral@bobek.cz>2010-06-30 08:56:42 +0200
committerAntonin Kral <a.kral@bobek.cz>2010-06-30 08:56:42 +0200
commit5c6a2219e6715bd7649c3fd28f58e6fb63d60a25 (patch)
tree1eda5f5ca9bd35190fe499a51119e855774b16c0 /db
parentdf7046adebaeb16716b5a2cebc6f34694f530caf (diff)
downloadmongodb-5c6a2219e6715bd7649c3fd28f58e6fb63d60a25.tar.gz
Imported Upstream version 1.4.4
Diffstat (limited to 'db')
-rw-r--r--db/concurrency.h57
-rw-r--r--db/database.h17
-rw-r--r--db/db.cpp24
-rw-r--r--db/instance.cpp8
-rw-r--r--db/pdfile.cpp9
-rw-r--r--db/repl.cpp19
-rw-r--r--db/stats/top.cpp2
-rw-r--r--db/update.cpp2
-rw-r--r--db/update.h12
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);
}
diff --git a/db/db.cpp b/db/db.cpp
index 51369bb..9be4031 100644
--- a/db/db.cpp
+++ b/db/db.cpp
@@ -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);
}