⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rwrecmutextest.cpp

📁 ICE-3.2 一个开源的中间件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    }    bool    hasWriteLock()    {        Lock sync(*this);        return _hasWriteLock;    }    //    // 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;    }private:    RWRecMutex& _m;    bool _destroyed;    bool _waitWrite;    bool _hasWriteLock;};typedef Handle<RWRecMutexWriteThread> RWRecMutexWriteThreadPtr;RWRecMutexTest::RWRecMutexTest() :    TestBase(rwRecMutexTestName){}voidRWRecMutexTest::run(){    RWRecMutex mutex;    RWRecMutexTestThreadPtr t;    ThreadControl control;    // TEST: TryLock (read)    {        RWRecMutex::RLock rlock(mutex);        // RLock testing        test(rlock.acquired());                try        {            rlock.acquire();            test(false);        }        catch(const ThreadLockedException&)        {            // Expected        }        try        {            rlock.tryAcquire();            test(false);        }        catch(const ThreadLockedException&)        {            // Expected        }        test(rlock.acquired());        rlock.release();        test(!rlock.acquired());        try        {            rlock.release();            test(false);        }        catch(const ThreadLockedException&)        {            // Expected        }                        test(rlock.tryAcquire() == true);        test(rlock.acquired());         RWRecMutex::RLock rlock2(mutex);                RWRecMutex::TryRLock trlock(mutex);        test(trlock.acquired());        RWRecMutex::TryWLock twlock(mutex);        test(!twlock.acquired());        RWRecMutex::TryWLock twlock2(mutex, Time::milliSeconds(10));        test(!twlock2.acquired());    }    // TEST: TryLock (write)    {        RWRecMutex::WLock wlock(mutex);        // WLock testing        test(wlock.acquired());                try        {            wlock.acquire();            test(false);        }        catch(const ThreadLockedException&)        {            // Expected        }        try        {            wlock.tryAcquire();            test(false);        }        catch(const ThreadLockedException&)        {            // Expected        }        test(wlock.acquired());        wlock.release();        test(!wlock.acquired());        try        {            wlock.release();            test(false);        }        catch(const ThreadLockedException&)        {            // Expected        }                        test(wlock.tryAcquire() == true);        test(wlock.acquired());         RWRecMutex::TryRLock trlock(mutex);        test(!trlock.acquired());                RWRecMutex::TryRLock trlock2(mutex, Time::milliSeconds(10));        test(!trlock2.acquired());                RWRecMutex::TryWLock twlock(mutex);        test(twlock.acquired());                RWRecMutex::TryWLock twlock2(mutex, Time::milliSeconds(10));        test(twlock2.acquired());    }    // TEST: read lock    {        RWRecMutex::RLock rlock(mutex);        // TEST: Start thread, try to acquire the mutex.        t = new RWRecMutexReadTestThread(mutex);        control = t->start();                // TEST: Wait until the tryLock has been tested.        t->waitTryLock();    }    //    // TEST: Once the mutex has been released, the thread should    // acquire the mutex and then terminate.    //    control.join();    // TEST: write lock    {        RWRecMutex::WLock wlock(mutex);        // TEST: Start thread, try to acquire the mutex.        t = new RWRecMutexWriteTestThread(mutex);        control = t->start();                // TEST: Wait until the tryLock has been tested.        t->waitTryLock();    }    //    // TEST: Once the mutex has been released, the thread should    // acquire the mutex and then terminate.    //    control.join();    // TEST: Lock precedence. Writers have precedence over readers.    {        RWRecMutex::RLock rlock(mutex);        // Start thread that tries to acquire write lock        t = new RWRecMutexWriteTestThread(mutex);        control = t->start();        // TEST: Wait until the tryLock has been tested. The thread is        // now waiting on a write lock.        t->waitTryLock();        // It's necessary for a small sleep here to ensure that the        // thread is actually waiting on a write lock.        ThreadControl::sleep(Time::seconds(1));        RWRecMutex::TryRLock trlock(mutex);        test(!trlock.acquired());    }    //    // TEST: Once the mutex has been released, the thread should    // acquire the mutex and then terminate.    //    control.join();    // TEST: Lock upgrading.    {        RWRecMutex::RLock rlock(mutex);        //        // Mutex now holds a write lock.        //        mutex.upgrade();        // Start thread that tries to acquire write lock        t = new RWRecMutexReadTestThread2(mutex);        control = t->start();        // TEST: Wait until the tryLock has been tested. The thread is        // now waiting on a read lock.        t->waitTryLock();        // It's necessary for a small sleep here to ensure that the        // thread is actually waiting on a read lock.        ThreadControl::sleep(Time::seconds(1));    }    //    // TEST: Once the mutex has been released, the thread should    // acquire the mutex and then terminate.    //    control.join();    //    // COMPILERBUG: Under Linux with gcc this causes the Mutex test to    // fail for some unknown reason. After spending more than enough    // time looking into this problem it was decided that this is a    // compiler bug of some sort.    //#if !(defined(__linux) && defined(__GNUC__))    // TEST: Lock upgrading. This time a reader thread is started    // first.    {        RWRecMutexUpgradeReadThreadPtr t1 = new RWRecMutexUpgradeReadThread(mutex);        control = t1->start();        // Wait for the thread to acquire the read lock.        t1->waitLock();        // Spawn a thread to try acquiring the lock        RWRecMutexUpgradeTestThreadPtr t2 = new RWRecMutexUpgradeTestThread(mutex);        ThreadControl control2 = t2->start();        t2->waitLock();        //        // Small sleep to find out whether the thread actually        // terminates (which means that the write lock upgrade was        // mistakenly acquired).        //        ThreadControl::sleep(Time::seconds(1));        test(!t2->upgradeAcquired());        //        // A read lock at this point should fail.        //        RWRecMutex::TryRLock trlock(mutex);        test(!trlock.acquired());                //        // As should a write lock.        //        RWRecMutex::TryWLock twlock(mutex);        test(!twlock.acquired());                //        // Once the read lock is released then the upgrade should        // succeed & the thread should terminate.        //        t1->signalUnlock();        control2.join();        control.join();        //        // Now both a read & write lock should be available.        //        {            RWRecMutex::WLock rlock2(mutex);        }        {            RWRecMutex::RLock rlock2(mutex);        }    }#endif    // TEST: Ensure that only one reader can upgrade to a writer.    // Other readers get a DeadlockException.    {        mutex.readLock();        RWRecMutexUpgradeThreadPtr t1 = new RWRecMutexUpgradeThread(mutex);        ThreadControl control1 = t1->start();        //        // Wait for the thread to get into the upgrade call. The        // upgrade will hang since the readLock is held by this thread        // and therefore cannot succeed until we release our read        // lock.        //        t1->waitUpgrade();        //        // Its necessary to sleep for 1 second to ensure that the        // thread is actually IN the upgrade and waiting.        //        ThreadControl::sleep(Time::seconds(1));        try        {            mutex.upgrade();            test(false);        }        catch(const DeadlockException&)        {        }        //        // Release the waiting thread, join.        //        mutex.unlock();        t1->destroy();        control1.join();        test(!t1->failed());    }    // TEST: Same as previous test, but for a timedUpgrade.    {        mutex.readLock();        RWRecMutexUpgradeThreadPtr t1 = new RWRecMutexUpgradeThread(mutex, true);        ThreadControl control1 = t1->start();        t1->waitUpgrade();        //        // Its necessary to sleep for 1 second to ensure that the        // thread is actually IN the upgrade and waiting.        //        ThreadControl::sleep(Time::seconds(1));        try        {            mutex.upgrade();            test(false);        }        catch(const DeadlockException&)        {        }        //        // Release the waiting thread, join.        //        mutex.unlock();        t1->destroy();        control1.join();        test(!t1->failed());    }    // TEST: Check that an upgrader is given preference over a writer.    {        mutex.readLock();        RWRecMutexUpgradeThreadPtr t1 = new RWRecMutexUpgradeThread(mutex);                ThreadControl control1 = t1->start();        //        // Its not necessary to sleep here, since the upgrade thread        // acquires the read lock before signalling. Therefore the        // write thread cannot get the write lock.        //        t1->waitUpgrade();
        RWRecMutexWriteThreadPtr t2 = new RWRecMutexWriteThread(mutex);
        ThreadControl control2 = t2->start();
        t2->waitWrite();        //
        // Its necessary to sleep for 1 second to ensure that the
        // thread is actually IN the write lock and waiting.
        //
        ThreadControl::sleep(Time::seconds(1));
        //        // Unlocking the read mutex lets the upgrade continue. At this        // point t1 should have the write-lock, and t2 should not.        //        test(!t2->hasWriteLock());        mutex.unlock();        //        // Wait for t1 to get the write lock. It will not release it        // until the thread is destroyed. t2 should not have the write        // lock.        //        test(!t1->failed());        test(t1->waitHasWriteLock());        test(!t2->hasWriteLock());        t1->destroy();        t2->destroy();        //        // After the thread has terminated the thread must have        // acquired the write lock.        //        test(t2->waitHasWriteLock());        control1.join();        control2.join();    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -