diff options
Diffstat (limited to 'src/mongo/util/concurrency/rwlockimpl.h')
-rw-r--r-- | src/mongo/util/concurrency/rwlockimpl.h | 215 |
1 files changed, 121 insertions, 94 deletions
diff --git a/src/mongo/util/concurrency/rwlockimpl.h b/src/mongo/util/concurrency/rwlockimpl.h index a591bd389b7..898197a9777 100644 --- a/src/mongo/util/concurrency/rwlockimpl.h +++ b/src/mongo/util/concurrency/rwlockimpl.h @@ -35,110 +35,137 @@ #if defined(NTDDI_VERSION) && defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7) // Windows slimreaderwriter version. Newer windows versions only. Under contention this is slower -// than boost::shared_mutex, but see https://jira.mongodb.org/browse/SERVER-2327 for why it cannot +// than boost::shared_mutex, but see https://jira.mongodb.org/browse/SERVER-2327 for why it cannot // be used. namespace mongo { - unsigned long long curTimeMicros64(); - - class RWLockBase { - MONGO_DISALLOW_COPYING(RWLockBase); - friend class SimpleRWLock; - SRWLOCK _lock; - protected: - RWLockBase() { InitializeSRWLock(&_lock); } - ~RWLockBase() { - // no special action needed to destroy a SRWLOCK - } - void lock() { AcquireSRWLockExclusive(&_lock); } - void unlock() { ReleaseSRWLockExclusive(&_lock); } - void lock_shared() { AcquireSRWLockShared(&_lock); } - void unlock_shared() { ReleaseSRWLockShared(&_lock); } - bool lock_shared_try( int millis ) { - if( TryAcquireSRWLockShared(&_lock) ) - return true; - if( millis == 0 ) - return false; - unsigned long long end = curTimeMicros64() + millis*1000; - while( 1 ) { - Sleep(1); - if( TryAcquireSRWLockShared(&_lock) ) - return true; - if( curTimeMicros64() >= end ) - break; - } +unsigned long long curTimeMicros64(); + +class RWLockBase { + MONGO_DISALLOW_COPYING(RWLockBase); + friend class SimpleRWLock; + SRWLOCK _lock; + +protected: + RWLockBase() { + InitializeSRWLock(&_lock); + } + ~RWLockBase() { + // no special action needed to destroy a SRWLOCK + } + void lock() { + AcquireSRWLockExclusive(&_lock); + } + void unlock() { + ReleaseSRWLockExclusive(&_lock); + } + void lock_shared() { + AcquireSRWLockShared(&_lock); + } + void unlock_shared() { + ReleaseSRWLockShared(&_lock); + } + bool lock_shared_try(int millis) { + if (TryAcquireSRWLockShared(&_lock)) + return true; + if (millis == 0) return false; - } - bool lock_try( int millis = 0 ) { - if( TryAcquireSRWLockExclusive(&_lock) ) // quick check to optimistically avoid calling curTimeMicros64 + unsigned long long end = curTimeMicros64() + millis * 1000; + while (1) { + Sleep(1); + if (TryAcquireSRWLockShared(&_lock)) return true; - if( millis == 0 ) - return false; - unsigned long long end = curTimeMicros64() + millis*1000; - do { - Sleep(1); - if( TryAcquireSRWLockExclusive(&_lock) ) - return true; - } while( curTimeMicros64() < end ); - return false; + if (curTimeMicros64() >= end) + break; } - // no upgradable for this impl - void lockAsUpgradable() { lock(); } - void unlockFromUpgradable() { unlock(); } - void upgrade() { } - public: - const char * implType() const { return "WINSRW"; } - }; + return false; + } + bool lock_try(int millis = 0) { + if (TryAcquireSRWLockExclusive( + &_lock)) // quick check to optimistically avoid calling curTimeMicros64 + return true; + if (millis == 0) + return false; + unsigned long long end = curTimeMicros64() + millis * 1000; + do { + Sleep(1); + if (TryAcquireSRWLockExclusive(&_lock)) + return true; + } while (curTimeMicros64() < end); + return false; + } + // no upgradable for this impl + void lockAsUpgradable() { + lock(); + } + void unlockFromUpgradable() { + unlock(); + } + void upgrade() {} + +public: + const char* implType() const { + return "WINSRW"; + } +}; } #else -# if defined(_WIN32) -# include "shared_mutex_win.hpp" -namespace mongo { typedef boost::modified_shared_mutex shared_mutex; } -# else -# include <boost/thread/shared_mutex.hpp> -namespace mongo { using boost::shared_mutex; } -# endif - -namespace mongo { - class RWLockBase { - MONGO_DISALLOW_COPYING(RWLockBase); - friend class SimpleRWLock; - shared_mutex _m; - protected: - RWLockBase() = default; - - void lock() { - _m.lock(); - } - void unlock() { - _m.unlock(); - } - void lockAsUpgradable() { - _m.lock_upgrade(); - } - void unlockFromUpgradable() { // upgradable -> unlocked - _m.unlock_upgrade(); - } - void upgrade() { // upgradable -> exclusive lock - _m.unlock_upgrade_and_lock(); - } - void lock_shared() { - _m.lock_shared(); - } - void unlock_shared() { - _m.unlock_shared(); - } - bool lock_shared_try( int millis ) { - return _m.timed_lock_shared( boost::posix_time::milliseconds(millis) ); - } - bool lock_try( int millis = 0 ) { - return _m.timed_lock( boost::posix_time::milliseconds(millis) ); - } - public: - const char * implType() const { return "boost"; } - }; +#if defined(_WIN32) +#include "shared_mutex_win.hpp" +namespace mongo { +typedef boost::modified_shared_mutex shared_mutex; +} +#else +#include <boost/thread/shared_mutex.hpp> +namespace mongo { +using boost::shared_mutex; +} +#endif + +namespace mongo { +class RWLockBase { + MONGO_DISALLOW_COPYING(RWLockBase); + friend class SimpleRWLock; + shared_mutex _m; + +protected: + RWLockBase() = default; + + void lock() { + _m.lock(); + } + void unlock() { + _m.unlock(); + } + void lockAsUpgradable() { + _m.lock_upgrade(); + } + void unlockFromUpgradable() { // upgradable -> unlocked + _m.unlock_upgrade(); + } + void upgrade() { // upgradable -> exclusive lock + _m.unlock_upgrade_and_lock(); + } + void lock_shared() { + _m.lock_shared(); + } + void unlock_shared() { + _m.unlock_shared(); + } + bool lock_shared_try(int millis) { + return _m.timed_lock_shared(boost::posix_time::milliseconds(millis)); + } + bool lock_try(int millis = 0) { + return _m.timed_lock(boost::posix_time::milliseconds(millis)); + } + +public: + const char* implType() const { + return "boost"; + } +}; } #endif |