mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
low priority rwlock defaults
This commit is contained in:
parent
bf441d1141
commit
141df23107
@ -233,6 +233,53 @@ namespace ThreadedTests {
|
||||
}
|
||||
};
|
||||
|
||||
class RWLockTest2 {
|
||||
public:
|
||||
|
||||
static void worker( const RWLock * lk , int * x ) {
|
||||
*x = 1;
|
||||
cout << "lock b try" << endl;
|
||||
rwlock b( *lk , true );
|
||||
cout << "lock b got" << endl;
|
||||
*x = 2;
|
||||
}
|
||||
|
||||
void run() {
|
||||
/**
|
||||
* note: this test will deadlock if the code breaks
|
||||
*/
|
||||
|
||||
RWLock lk( "eliot2" , 10000 );
|
||||
|
||||
auto_ptr<rwlock> a( new rwlock( lk , false ) );
|
||||
|
||||
int x = 0;
|
||||
boost::thread t( boost::bind( worker , &lk , &x ) );
|
||||
while ( ! x );
|
||||
assert( x == 1 );
|
||||
sleepmillis( 500 );
|
||||
assert( x == 1 );
|
||||
|
||||
cout << "lock c try" << endl;
|
||||
auto_ptr<rwlock> c( new rwlock( lk , false ) );
|
||||
cout << "lock c got" << endl;
|
||||
|
||||
c.reset();
|
||||
a.reset();
|
||||
|
||||
for ( int i=0; i<2000; i++ ) {
|
||||
if ( x == 2 )
|
||||
break;
|
||||
sleepmillis(1);
|
||||
}
|
||||
|
||||
assert( x == 2 );
|
||||
t.join();
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class All : public Suite {
|
||||
public:
|
||||
All() : Suite( "threading" ) {
|
||||
@ -244,6 +291,7 @@ namespace ThreadedTests {
|
||||
add< ThreadPoolTest >();
|
||||
add< LockTest >();
|
||||
add< RWLockTest1 >();
|
||||
add< RWLockTest2 >();
|
||||
add< MongoMutexTest >();
|
||||
}
|
||||
} myall;
|
||||
|
@ -57,8 +57,9 @@ namespace mongo {
|
||||
|
||||
class RWLock {
|
||||
public:
|
||||
RWLock(const char *) { InitializeSRWLock(&_lock); }
|
||||
RWLock(const char *, int lowPriorityWaitMS=0 ) { _lowPriorityWaitMS=lowPriorityWaitMS; InitializeSRWLock(&_lock); }
|
||||
~RWLock() { }
|
||||
int lowPriorityWaitMS() const { return _lowPriorityWaitMS; }
|
||||
void lock() { AcquireSRWLockExclusive(&_lock); }
|
||||
void unlock() { ReleaseSRWLockExclusive(&_lock); }
|
||||
void lock_shared() { AcquireSRWLockShared(&_lock); }
|
||||
@ -87,18 +88,23 @@ namespace mongo {
|
||||
}
|
||||
private:
|
||||
SRWLOCK _lock;
|
||||
int _lowPriorityWaitMS();
|
||||
};
|
||||
|
||||
#elif defined(BOOST_RWLOCK)
|
||||
class RWLock {
|
||||
shared_mutex _m;
|
||||
int _lowPriorityWaitMS;
|
||||
public:
|
||||
#if defined(_DEBUG)
|
||||
const char *_name;
|
||||
RWLock(const char *name) : _name(name) { }
|
||||
RWLock(const char *name, int lowPriorityWait=0) : _lowPriorityWaitMS(lowPriorityWait) , _name(name) { }
|
||||
#else
|
||||
RWLock(const char *) { }
|
||||
RWLock(const char *, int lowPriorityWait=0) : _lowPriorityWaitMS(lowPriorityWait) { }
|
||||
#endif
|
||||
|
||||
int lowPriorityWaitMS() const { return _lowPriorityWaitMS; }
|
||||
|
||||
void lock() {
|
||||
_m.lock();
|
||||
#if defined(_DEBUG)
|
||||
@ -121,18 +127,14 @@ namespace mongo {
|
||||
}
|
||||
|
||||
bool lock_shared_try( int millis ) {
|
||||
boost::system_time until = get_system_time();
|
||||
until += boost::posix_time::milliseconds(millis);
|
||||
if( _m.timed_lock_shared( until ) ) {
|
||||
if( _m.timed_lock_shared( boost::posix_time::milliseconds(millis) ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lock_try( int millis = 0 ) {
|
||||
boost::system_time until = get_system_time();
|
||||
until += boost::posix_time::milliseconds(millis);
|
||||
if( _m.timed_lock( until ) ) {
|
||||
if( _m.timed_lock( boost::posix_time::milliseconds(millis) ) ) {
|
||||
#if defined(_DEBUG)
|
||||
mutexDebugger.entering(_name);
|
||||
#endif
|
||||
@ -255,13 +257,16 @@ namespace mongo {
|
||||
: _lock( (RWLock&)lock ) , _write( write ) {
|
||||
|
||||
if ( ! alreadyHaveLock ) {
|
||||
|
||||
|
||||
if ( _write ) {
|
||||
|
||||
if ( ! lowPriorityWaitMS && lock.lowPriorityWaitMS() )
|
||||
lowPriorityWaitMS = lock.lowPriorityWaitMS();
|
||||
|
||||
if ( lowPriorityWaitMS ) {
|
||||
bool got = false;
|
||||
for ( int i=0; i<lowPriorityWaitMS/2; i++ ) { // we divide by 2 since we sleep a bit
|
||||
if ( _lock.lock_try(1) ) {
|
||||
for ( int i=0; i<lowPriorityWaitMS; i++ ) { // we divide by 2 since we sleep a bit
|
||||
if ( _lock.lock_try(0) ) {
|
||||
got = true;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user