📄 rwrecmutextest.cpp
字号:
// **********************************************************************//// Copyright (c) 2003-2007 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.//// **********************************************************************#include <IceUtil/IceUtil.h>#include <RWRecMutexTest.h>#include <TestCommon.h>using namespace std;using namespace IceUtil;static const std::string rwRecMutexTestName("read/write recursive mutex");class RWRecMutexTestThread : public Thread{public: RWRecMutexTestThread(RWRecMutex& m) : _mutex(m), _tryLock(false) { } void waitTryLock() { Mutex::Lock lock(_tryLockMutex); while(!_tryLock) { _tryLockCond.wait(lock); } }protected: RWRecMutex& _mutex; bool _tryLock; // // Use native Condition variable here, not Monitor. // Cond _tryLockCond; Mutex _tryLockMutex;};class RWRecMutexReadTestThread : public RWRecMutexTestThread{public: RWRecMutexReadTestThread(RWRecMutex& m) : RWRecMutexTestThread(m) { } virtual void run() { RWRecMutex::TryRLock tlock(_mutex); test(tlock.acquired()); { Mutex::Lock lock(_tryLockMutex); _tryLock = true; } _tryLockCond.signal(); RWRecMutex::RLock lock(_mutex); }};class RWRecMutexReadTestThread2 : public RWRecMutexTestThread{public: RWRecMutexReadTestThread2(RWRecMutex& m) : RWRecMutexTestThread(m) { } virtual void run() { RWRecMutex::TryRLock tlock(_mutex); test(!tlock.acquired()); { Mutex::Lock lock(_tryLockMutex); _tryLock = true; } _tryLockCond.signal(); RWRecMutex::RLock lock(_mutex); }};class RWRecMutexUpgradeReadThread : public Thread{public: RWRecMutexUpgradeReadThread(RWRecMutex& m) : _mutex(m), _unlock(false), _lock(false) { } virtual void run() { RWRecMutex::RLock lock(_mutex); signalLock(); waitUnlock(); } void waitUnlock() { Mutex::Lock lock(_unlockMutex); while(!_unlock) { _unlockCond.wait(lock); } } void signalUnlock() { Mutex::Lock lock(_unlockMutex); _unlock = true; _unlockCond.signal(); } void signalLock() { Mutex::Lock lock(_lockMutex); _lock = true; _lockCond.signal(); } void waitLock() { Mutex::Lock lock(_lockMutex); while(!_lock) { _lockCond.wait(lock); } }private: RWRecMutex& _mutex; // // Use native Condition variable here, not Monitor. // Cond _unlockCond; Mutex _unlockMutex; bool _unlock; Cond _lockCond; Mutex _lockMutex; bool _lock;};typedef Handle<RWRecMutexUpgradeReadThread> RWRecMutexUpgradeReadThreadPtr;class RWRecMutexUpgradeTestThread : public Thread{public: RWRecMutexUpgradeTestThread(RWRecMutex& m) : _mutex(m), _lock(false), _upgradeAcquired(false) { } virtual void run() { RWRecMutex::RLock lock(_mutex); signalLock(); lock.upgrade(); _upgradeAcquired = true; } void signalLock() { Mutex::Lock lock(_lockMutex); _lock = true; _lockCond.signal(); } void waitLock() { Mutex::Lock lock(_lockMutex); while(!_lock) { _lockCond.wait(lock); } } bool upgradeAcquired() const { return _upgradeAcquired; }private: RWRecMutex& _mutex; // // Use native Condition variable here, not Monitor. // Cond _lockCond; Mutex _lockMutex; bool _lock; bool _upgradeAcquired;};typedef Handle<RWRecMutexUpgradeTestThread> RWRecMutexUpgradeTestThreadPtr;class RWRecMutexWriteTestThread : public RWRecMutexTestThread{public: RWRecMutexWriteTestThread(RWRecMutex& m) : RWRecMutexTestThread(m) { } virtual void run() { RWRecMutex::TryWLock tlock(_mutex); test(!tlock.acquired()); { Mutex::Lock lock(_tryLockMutex); _tryLock = true; } _tryLockCond.signal(); RWRecMutex::WLock lock(_mutex); }};typedef Handle<RWRecMutexTestThread> RWRecMutexTestThreadPtr;class RWRecMutexUpgradeThread : public Thread, public IceUtil::Monitor<IceUtil::Mutex>{public: RWRecMutexUpgradeThread(RWRecMutex& m, bool timed = false) : _m(m), _timed(timed), _destroyed(false), _upgrading(false), _hasWriteLock(false), _failed(false) { } virtual void run() { // // Acquire a read lock. // RWRecMutex::RLock tlock(_m); { Lock sync(*this); _upgrading = true; notify(); } try { if(_timed) { if(!_m.timedUpgrade(IceUtil::Time::seconds(10))) { _failed = true; } } else { _m.upgrade(); } } catch(DeadlockException&) { _failed = true; } { Lock sync(*this); _hasWriteLock = true; notify(); while(!_destroyed) { wait(); } } } void waitUpgrade() { Lock sync(*this); // // Wait for the _upgrading flag to be set. // while(!_upgrading) { wait(); } } void destroy() { Lock sync(*this); _destroyed = true; notify(); } // // This waits a maximum of N seconds if the lock is not already // acquired. It could while forever, but that would cause the test // to hang in the event of a failure. // bool waitHasWriteLock() { Lock sync(*this); if(!_hasWriteLock) { timedWait(Time::seconds(10)); } return _hasWriteLock; } bool failed() const { return _failed; }private: RWRecMutex& _m; bool _timed; bool _destroyed; bool _upgrading; bool _hasWriteLock; bool _failed;};typedef Handle<RWRecMutexUpgradeThread> RWRecMutexUpgradeThreadPtr;class RWRecMutexWriteThread : public Thread, public IceUtil::Monitor<IceUtil::Mutex>{public: RWRecMutexWriteThread(RWRecMutex& m) : _m(m), _destroyed(false), _waitWrite(false), _hasWriteLock(false) { } virtual void run() { { Lock sync(*this); _waitWrite = true; notify(); } // // Acquire a read lock. // RWRecMutex::WLock sync(_m); { Lock sync(*this); _hasWriteLock = true; notify(); while(!_destroyed) { wait(); } } } void waitWrite() { Lock sync(*this); // // Wait for the _upgrading flag to be set. // while(!_waitWrite) { wait(); } // // Its necessary to sleep for 1 second to ensure that the // thread is actually IN the upgrade and waiting. // ThreadControl::sleep(Time::seconds(1)); } void destroy() { Lock sync(*this); _destroyed = true; notify();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -