summaryrefslogtreecommitdiff
path: root/db/concurrency.h
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2010-06-08 11:04:18 -0400
committerEliot Horowitz <eliot@10gen.com>2010-06-08 11:04:18 -0400
commit74fe4041a0b25917bc13ad5d8644b46a09cebde7 (patch)
tree4b8cce478b6cacca9f2d392c9a9f2e08fee4531a /db/concurrency.h
parent68bcdb17fbebd8d071e6fca845dacd6e940813c2 (diff)
downloadmongo-74fe4041a0b25917bc13ad5d8644b46a09cebde7.tar.gz
repl: logKeepAlive can block readers SERVER-1202
Diffstat (limited to 'db/concurrency.h')
-rw-r--r--db/concurrency.h57
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 ){