diff options
Diffstat (limited to 'cpp/src/IceUtil/RWRecMutex.cpp')
-rw-r--r-- | cpp/src/IceUtil/RWRecMutex.cpp | 448 |
1 files changed, 0 insertions, 448 deletions
diff --git a/cpp/src/IceUtil/RWRecMutex.cpp b/cpp/src/IceUtil/RWRecMutex.cpp deleted file mode 100644 index e165efeb452..00000000000 --- a/cpp/src/IceUtil/RWRecMutex.cpp +++ /dev/null @@ -1,448 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -// -// We disable deprecation warning here, to allow clean compilation of -// of deprecated methods. -// -#ifdef _MSC_VER -# pragma warning( disable : 4996 ) -#endif - -#include <IceUtil/RWRecMutex.h> -#include <IceUtil/Exception.h> -#include <IceUtil/Time.h> - -IceUtil::DeadlockException::DeadlockException(const char* file, int line) : - Exception(file, line) -{ -} - -const char* IceUtil::DeadlockException::_name = "IceUtil::DeadlockException"; - -::std::string -IceUtil::DeadlockException::ice_name() const -{ - return _name; -} - -IceUtil::Exception* -IceUtil::DeadlockException::ice_clone() const -{ - return new DeadlockException(*this); -} - -void -IceUtil::DeadlockException::ice_throw() const -{ - throw *this; -} - -IceUtil::RWRecMutex::RWRecMutex() : - _count(0), - _waitingWriters(0), - _upgrading(false) -{ -} - -IceUtil::RWRecMutex::~RWRecMutex() -{ -} - -void -IceUtil::RWRecMutex::readLock() const -{ - Mutex::Lock lock(_mutex); - - // - // Wait while a writer holds the lock or while writers or an upgrader - // are waiting to get the lock. - // - while(_count < 0 || _waitingWriters != 0) - { - _readers.wait(lock); - } - ++_count; -} - -bool -IceUtil::RWRecMutex::tryReadLock() const -{ - Mutex::Lock lock(_mutex); - - // - // Would block if a writer holds the lock or if writers or an upgrader - // are waiting to get the lock. - // - if(_count < 0 || _waitingWriters != 0) - { - return false; - } - ++_count; - return true; -} - -bool -IceUtil::RWRecMutex::timedReadLock(const Time& timeout) const -{ - Mutex::Lock lock(_mutex); - - // - // Wait while a writer holds the lock or while writers or an upgrader - // are waiting to get the lock. - // - Time end = Time::now(Time::Monotonic) + timeout; - while(_count < 0 || _waitingWriters != 0) - { - Time remainder = end - Time::now(Time::Monotonic); - if(remainder > Time()) - { - if(_readers.timedWait(lock, remainder) == false) - { - return false; - } - } - else - { - return false; - } - } - - ++_count; - return true; -} - -void -IceUtil::RWRecMutex::writeLock() const -{ - Mutex::Lock lock(_mutex); - - // - // If the mutex is already write locked by this writer then - // decrement _count, and return. - // - if(_count < 0 && _writerId == ThreadControl()) - { - --_count; - return; - } - - // - // Wait for the lock to become available and increment the number - // of waiting writers. - // - while(_count != 0) - { - ++_waitingWriters; - try - { - _writers.wait(lock); - } - catch(...) - { - --_waitingWriters; - throw; - } - --_waitingWriters; - } - - // - // Got the lock, indicate it's held by a writer. - // - _count = -1; - _writerId = ThreadControl(); -} - -bool -IceUtil::RWRecMutex::tryWriteLock() const -{ - Mutex::Lock lock(_mutex); - - // - // If the mutex is already write locked by this writer then - // decrement _count, and return. - // - if(_count < 0 && _writerId == ThreadControl()) - { - --_count; - return true; - } - - // - // If there are readers or another writer then the call would block. - // - if(_count != 0) - { - return false; - } - - // - // Got the lock, indicate it's held by a writer. - // - _count = -1; - _writerId = ThreadControl(); - return true; -} - -bool -IceUtil::RWRecMutex::timedWriteLock(const Time& timeout) const -{ - Mutex::Lock lock(_mutex); - - // - // If the mutex is already write locked by this writer then - // decrement _count, and return. - if(_count < 0 && _writerId == ThreadControl()) - { - --_count; - return true; - } - - // - // Wait for the lock to become available and increment the number - // of waiting writers. - // - Time end = Time::now(Time::Monotonic) + timeout; - while(_count != 0) - { - Time remainder = end - Time::now(Time::Monotonic); - if(remainder > Time()) - { - ++_waitingWriters; - try - { - bool result = _writers.timedWait(lock, remainder); - --_waitingWriters; - if(result == false) - { - return false; - } - } - catch(...) - { - --_waitingWriters; - throw; - } - } - else - { - return false; - } - } - - // - // Got the lock, indicate it's held by a writer. - // - _count = -1; - _writerId = ThreadControl(); - return true; -} - -void -IceUtil::RWRecMutex::unlock() const -{ - bool ww = false; - bool wr = false; - { - Mutex::Lock lock(_mutex); - - assert(_count != 0); - - // - // If _count < 0, the calling thread is a writer that holds the - // lock, so release the lock. Otherwise, _count is guaranteed to - // be > 0, so the calling thread is a reader releasing the lock. - // - if(_count < 0) - { - // - // Writer called unlock - // - ++_count; - - // - // If the write lock wasn't totally released we're done. - // - if(_count != 0) - { - return; - } - } - else - { - // - // Reader called unlock - // - --_count; - } - - // - // Writers are waiting (ww) if _waitingWriters > 0. In that - // case, it's OK to let another writer into the region once there - // are no more readers (_count == 0). Otherwise, no writers are - // waiting but readers may be waiting (wr). - // - ww = (_waitingWriters != 0 && _count == 0); - wr = (_waitingWriters == 0); - } // Unlock mutex. - - // - // Wake up a waiting writer if there is one. If not, wake up all - // readers (just in case--there may be none). - // - if(ww) - { - if(_upgrading) - { - // - // If there is an untimed upgrader, it runs. - // - _upgrader.signal(); - } - else - { - // - // Wake a normal writer. - // - _writers.signal(); - } - } - else if(wr) - { - // - // Wake readers - // - _readers.broadcast(); - } -} - -void -IceUtil::RWRecMutex::upgrade() const -{ - Mutex::Lock lock(_mutex); - - if(_upgrading) - { - throw DeadlockException(__FILE__, __LINE__); - } - - // - // Reader owns at least one count. - // - assert(_count > 0); - --_count; - - // - // Wait to acquire the write lock. - // - _upgrading = true; - while(_count != 0) - { - ++_waitingWriters; - try - { - _upgrader.wait(lock); - } - catch(...) - { - _upgrading = false; - --_waitingWriters; - ++_count; - throw; - } - --_waitingWriters; - } - - // - // Got the lock, indicate it's held by a writer. - // - _count = -1; - _writerId = ThreadControl(); - _upgrading = false; -} - -bool -IceUtil::RWRecMutex::timedUpgrade(const Time& timeout) const -{ - Mutex::Lock lock(_mutex); - - // - // If another reader is already waiting for an upgrade, - // this upgrade cannot possibly succeed. - // - if(_upgrading) - { - return false; - } - - // Reader owns at least one count - // - assert(_count > 0); - --_count; - - // - // Wait to acquire the write lock. - // - _upgrading = true; - Time end = Time::now(Time::Monotonic) + timeout; - while(_count != 0) - { - Time remainder = end - Time::now(Time::Monotonic); - if(remainder > Time()) - { - ++_waitingWriters; - try - { - bool result = _upgrader.timedWait(lock, remainder); - --_waitingWriters; - if(!result) - { - _upgrading = false; - ++_count; - return false; - } - } - catch(...) - { - _upgrading = false; - --_waitingWriters; - ++_count; - throw; - } - } - else - { - // - // The lock isn't acquired if a timeout occurred. - // - ++_count; - _upgrading = false; - return false; - } - } - - // - // Got the lock, indicate it's held by a writer. - // - _count = -1; - _writerId = ThreadControl(); - _upgrading = false; - return true; -} - -void -IceUtil::RWRecMutex::downgrade() const -{ - Mutex::Lock lock(_mutex); - - if(++_count == 0) - { - _count = 1; - } -} |