diff options
author | Eliot Horowitz <eliot@10gen.com> | 2010-06-08 11:04:18 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2010-06-08 11:04:18 -0400 |
commit | 74fe4041a0b25917bc13ad5d8644b46a09cebde7 (patch) | |
tree | 4b8cce478b6cacca9f2d392c9a9f2e08fee4531a /db/concurrency.h | |
parent | 68bcdb17fbebd8d071e6fca845dacd6e940813c2 (diff) | |
download | mongo-74fe4041a0b25917bc13ad5d8644b46a09cebde7.tar.gz |
repl: logKeepAlive can block readers SERVER-1202
Diffstat (limited to 'db/concurrency.h')
-rw-r--r-- | db/concurrency.h | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/db/concurrency.h b/db/concurrency.h index de8f242d61f..5c5c11c9c9a 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,23 @@ namespace mongo { _minfo.entered(); } + + bool lock_try() { + if ( _checkWriteLockAlready() ) + return true; + + curopWaitingForLock( 1 ); + bool got = _m.try_lock(); + curopGotLock(); + + if ( got ){ + _minfo.entered(); + _state.set(1); + } + + return got; + } + void unlock() { //DEV cout << "UNLOCK" << endl; int s = _state.get(); @@ -227,12 +254,21 @@ 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(){ + bool got = boost::detail::thread::lock_ops<boost::recursive_mutex>::trylock(m); + if ( got ){ + _minfo.entered(); + } + return got; + } + 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 ){ |