concurrency.h   concurrency.h 
skipping to change at line 116 skipping to change at line 116
* < 0 read lock * < 0 read lock
*/ */
int getState(){ return _state.get(); } int getState(){ return _state.get(); }
void assertWriteLocked() { void assertWriteLocked() {
assert( getState() > 0 ); assert( getState() > 0 );
DEV assert( !_releasedEarly.get() ); DEV assert( !_releasedEarly.get() );
} }
bool atLeastReadLocked() { return _state.get() != 0; } bool atLeastReadLocked() { return _state.get() != 0; }
void assertAtLeastReadLocked() { assert(atLeastReadLocked()); } void assertAtLeastReadLocked() { assert(atLeastReadLocked()); }
void lock() { bool _checkWriteLockAlready(){
//DEV cout << "LOCK" << endl; //DEV cout << "LOCK" << endl;
DEV assert( haveClient() ); DEV assert( haveClient() );
int s = _state.get(); int s = _state.get();
if( s > 0 ) { if( s > 0 ) {
_state.set(s+1); _state.set(s+1);
return; return true;
} }
massert( 10293 , (string)"internal error: locks are not upgrade able: " + sayClientState() , s == 0 ); massert( 10293 , (string)"internal error: locks are not upgrade able: " + sayClientState() , s == 0 );
return false;
}
void lock() {
if ( _checkWriteLockAlready() )
return;
_state.set(1); _state.set(1);
curopWaitingForLock( 1 ); curopWaitingForLock( 1 );
_m.lock(); _m.lock();
curopGotLock(); curopGotLock();
_minfo.entered(); _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() { void unlock() {
//DEV cout << "UNLOCK" << endl; //DEV cout << "UNLOCK" << endl;
int s = _state.get(); int s = _state.get();
if( s > 1 ) { if( s > 1 ) {
_state.set(s-1); _state.set(s-1);
return; return;
} }
if( s != 1 ) { if( s != 1 ) {
if( _releasedEarly.get() ) { if( _releasedEarly.get() ) {
_releasedEarly.set(false); _releasedEarly.set(false);
skipping to change at line 230 skipping to change at line 260
/* this will be for old versions of boost */ /* this will be for old versions of boost */
class MongoMutex { class MongoMutex {
MutexInfo _minfo; MutexInfo _minfo;
boost::recursive_mutex m; boost::recursive_mutex m;
ThreadLocalValue<bool> _releasedEarly; ThreadLocalValue<bool> _releasedEarly;
public: public:
MongoMutex() { } MongoMutex() { }
void lock() { void lock() {
#ifdef HAVE_READLOCK #ifdef HAVE_READLOCK
m.lock(); m.lock();
#error this should be impossible?
#else #else
boost::detail::thread::lock_ops<boost::recursive_mutex>::lock(m ); boost::detail::thread::lock_ops<boost::recursive_mutex>::lock(m );
#endif #endif
_minfo.entered(); _minfo.entered();
} }
bool lock_try(){
lock();
return true;
}
void releaseEarly() { void releaseEarly() {
assertWriteLocked(); // aso must not be recursive, although we don't verify that in the old boost version assertWriteLocked(); // aso must not be recursive, although we don't verify that in the old boost version
assert( !_releasedEarly.get() ); assert( !_releasedEarly.get() );
_releasedEarly.set(true); _releasedEarly.set(true);
_unlock(); _unlock();
} }
void _unlock() { void _unlock() {
_minfo.leaving(); _minfo.leaving();
#ifdef HAVE_READLOCK #ifdef HAVE_READLOCK
skipping to change at line 330 skipping to change at line 366
dbunlocking_read(); dbunlocking_read();
dbMutex.unlock_shared(); dbMutex.unlock_shared();
} }
} }
bool got(){ bool got(){
return _got; return _got;
} }
bool _got; 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 { struct atleastreadlock {
atleastreadlock( const string& ns ){ atleastreadlock( const string& ns ){
_prev = dbMutex.getState(); _prev = dbMutex.getState();
if ( _prev == 0 ) if ( _prev == 0 )
dbMutex.lock_shared(); dbMutex.lock_shared();
} }
~atleastreadlock(){ ~atleastreadlock(){
if ( _prev == 0 ) if ( _prev == 0 )
dbMutex.unlock_shared(); dbMutex.unlock_shared();
} }
 End of changes. 8 change blocks. 
2 lines changed or deleted 54 lines changed or added


 database.h   database.h 
skipping to change at line 156 skipping to change at line 156
throw; throw;
} }
if ( preallocateOnly ) if ( preallocateOnly )
delete p; delete p;
else else
files[n] = p; files[n] = p;
} }
return preallocateOnly ? 0 : p; return preallocateOnly ? 0 : p;
} }
MongoDataFile* addAFile( int sizeNeeded = 0, bool preallocateNextFi le = false ) { MongoDataFile* addAFile( int sizeNeeded, bool preallocateNextFile ) {
int n = (int) files.size(); int n = (int) files.size();
MongoDataFile *ret = getFile( n, sizeNeeded ); MongoDataFile *ret = getFile( n, sizeNeeded );
if ( preallocateNextFile ) if ( preallocateNextFile )
preallocateAFile(); preallocateAFile();
return ret; return ret;
} }
// safe to call this multiple times - the implementation will only preallocate one file // safe to call this multiple times - the implementation will only preallocate one file
void preallocateAFile() { void preallocateAFile() {
int n = (int) files.size(); int n = (int) files.size();
getFile( n, 0, true ); getFile( n, 0, true );
} }
MongoDataFile* suitableFile( int sizeNeeded ) { MongoDataFile* suitableFile( int sizeNeeded, bool preallocate ) {
MongoDataFile* f = newestFile(); MongoDataFile* f = newestFile();
if ( !f ) {
f = addAFile( sizeNeeded, preallocate );
}
for ( int i = 0; i < 8; i++ ) { for ( int i = 0; i < 8; i++ ) {
if ( f->getHeader()->unusedLength >= sizeNeeded ) if ( f->getHeader()->unusedLength >= sizeNeeded )
break; 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 if ( f->getHeader()->fileLength >= MongoDataFile::maxSize() ) // this is as big as they get so might as well stop
break; break;
} }
return f; return f;
} }
Extent* allocExtent( const char *ns, int size, bool capped ) { Extent* allocExtent( const char *ns, int size, bool capped ) {
Extent *e = DataFileMgr::allocFromFreeList( ns, size, capped ); Extent *e = DataFileMgr::allocFromFreeList( ns, size, capped );
if( e ) return e; if( e ) return e;
return suitableFile( size )->createExtent( ns, size, capped ); return suitableFile( size, !capped )->createExtent( ns, size, c apped );
} }
MongoDataFile* newestFile() { MongoDataFile* newestFile() {
int n = (int) files.size(); int n = (int) files.size();
if ( n > 0 ) n--; if ( n > 0 ) {
n--;
} else {
return 0;
}
return getFile(n); return getFile(n);
} }
/** /**
* @return true if success, false otherwise * @return true if success, false otherwise
*/ */
bool setProfilingLevel( int newLevel , string& errmsg ); bool setProfilingLevel( int newLevel , string& errmsg );
void finishInit(); void finishInit();
 End of changes. 6 change blocks. 
5 lines changed or deleted 12 lines changed or added


 update.h   update.h 
skipping to change at line 415 skipping to change at line 415
// TODO: should we convert this to $set? // TODO: should we convert this to $set?
return false; return false;
default: default:
return false; return false;
} }
} }
void appendForOpLog( BSONObjBuilder& b ) const { void appendForOpLog( BSONObjBuilder& b ) const {
if ( incType ){ if ( incType ){
BSONObjBuilder bb( b.subobjStart( "$set" ) ); BSONObjBuilder bb( b.subobjStart( "$set" ) );
appendIncValue( bb ); appendIncValue( bb , true );
bb.done(); bb.done();
return; return;
} }
const char * name = fixedOpName ? fixedOpName : Mod::modNames[o p()]; const char * name = fixedOpName ? fixedOpName : Mod::modNames[o p()];
BSONObjBuilder bb( b.subobjStart( name ) ); BSONObjBuilder bb( b.subobjStart( name ) );
if ( fixed ) if ( fixed )
bb.appendAs( *fixed , m->fieldName ); bb.appendAs( *fixed , m->fieldName );
else else
bb.appendAs( m->elt , m->fieldName ); bb.appendAs( m->elt , m->fieldName );
bb.done(); bb.done();
} }
template< class Builder > template< class Builder >
void apply( Builder& b , BSONElement in ){ void apply( Builder& b , BSONElement in ){
m->apply( b , in , *this ); m->apply( b , in , *this );
} }
template< class Builder > 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 ){ switch ( incType ){
case NumberDouble: case NumberDouble:
b.append( m->shortFieldName , incdouble ); break; b.append( n , incdouble ); break;
case NumberLong: case NumberLong:
b.append( m->shortFieldName , inclong ); break; b.append( n , inclong ); break;
case NumberInt: case NumberInt:
b.append( m->shortFieldName , incint ); break; b.append( n , incint ); break;
default: default:
assert(0); assert(0);
} }
} }
}; };
/** /**
* this is used to hold state, meta data while applying a ModSet to a B SONObj * this is used to hold state, meta data while applying a ModSet to a B SONObj
* the goal is to make ModSet const so its re-usable * the goal is to make ModSet const so its re-usable
*/ */
 End of changes. 5 change blocks. 
5 lines changed or deleted 8 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/