diff options
Diffstat (limited to 'tests/auto/qwaitcondition/tst_qwaitcondition.cpp')
-rw-r--r-- | tests/auto/qwaitcondition/tst_qwaitcondition.cpp | 859 |
1 files changed, 435 insertions, 424 deletions
diff --git a/tests/auto/qwaitcondition/tst_qwaitcondition.cpp b/tests/auto/qwaitcondition/tst_qwaitcondition.cpp index 87a895a6cf..7d7fb2d3d4 100644 --- a/tests/auto/qwaitcondition/tst_qwaitcondition.cpp +++ b/tests/auto/qwaitcondition/tst_qwaitcondition.cpp @@ -47,6 +47,12 @@ #include <qthread.h> #include <qwaitcondition.h> +#if defined(Q_OS_SYMBIAN) +// Symbian Open C has a bug that causes very short waits to fail sometimes +#define COND_WAIT_TIME 50 +#else +#define COND_WAIT_TIME 1 +#endif //TESTED_CLASS= @@ -92,10 +98,10 @@ public: void run() { - mutex.lock(); - cond.wakeOne(); - cond.wait(&mutex); - mutex.unlock(); + mutex.lock(); + cond.wakeOne(); + cond.wait(&mutex); + mutex.unlock(); } }; @@ -108,15 +114,15 @@ public: QWaitCondition *cond; inline wait_QMutex_Thread_2() - : mutex(0), cond(0) + : mutex(0), cond(0) { } void run() { - mutex->lock(); - started.wakeOne(); - cond->wait(mutex); - mutex->unlock(); + mutex->lock(); + started.wakeOne(); + cond->wait(mutex); + mutex->unlock(); } }; @@ -131,10 +137,10 @@ public: void run() { - readWriteLock.lockForWrite(); - cond.wakeOne(); - cond.wait(&readWriteLock); - readWriteLock.unlock(); + readWriteLock.lockForWrite(); + cond.wakeOne(); + cond.wait(&readWriteLock); + readWriteLock.unlock(); } }; @@ -147,15 +153,15 @@ public: QWaitCondition *cond; inline wait_QReadWriteLock_Thread_2() - : readWriteLock(0), cond(0) + : readWriteLock(0), cond(0) { } void run() { - readWriteLock->lockForRead(); - started.wakeOne(); - cond->wait(readWriteLock); - readWriteLock->unlock(); + readWriteLock->lockForRead(); + started.wakeOne(); + cond->wait(readWriteLock); + readWriteLock->unlock(); } }; @@ -163,79 +169,79 @@ void tst_QWaitCondition::wait_QMutex() { int x; for (int i = 0; i < iterations; ++i) { - { - QMutex mutex; - QWaitCondition cond; - - mutex.lock(); - - cond.wakeOne(); - QVERIFY(!cond.wait(&mutex, 1)); - - cond.wakeAll(); - QVERIFY(!cond.wait(&mutex, 1)); - - mutex.unlock(); - } - - { - // test multiple threads waiting on separate wait conditions - wait_QMutex_Thread_1 thread[ThreadCount]; - - for (x = 0; x < ThreadCount; ++x) { - thread[x].mutex.lock(); - thread[x].start(); - // wait for thread to start - QVERIFY(thread[x].cond.wait(&thread[x].mutex, 1000)); - thread[x].mutex.unlock(); - } - - for (x = 0; x < ThreadCount; ++x) { - QVERIFY(thread[x].isRunning()); - QVERIFY(!thread[x].isFinished()); - } - - for (x = 0; x < ThreadCount; ++x) { - thread[x].mutex.lock(); - thread[x].cond.wakeOne(); - thread[x].mutex.unlock(); - } - - for (x = 0; x < ThreadCount; ++x) { - QVERIFY(thread[x].wait(1000)); - } - } - - { - // test multiple threads waiting on a wait condition - QMutex mutex; - QWaitCondition cond1, cond2; - wait_QMutex_Thread_2 thread[ThreadCount]; - - mutex.lock(); - for (x = 0; x < ThreadCount; ++x) { - thread[x].mutex = &mutex; - thread[x].cond = (x < ThreadCount / 2) ? &cond1 : &cond2; - thread[x].start(); - // wait for thread to start - QVERIFY(thread[x].started.wait(&mutex, 1000)); - } - mutex.unlock(); - - for (x = 0; x < ThreadCount; ++x) { - QVERIFY(thread[x].isRunning()); - QVERIFY(!thread[x].isFinished()); - } - - mutex.lock(); - cond1.wakeAll(); - cond2.wakeAll(); - mutex.unlock(); - - for (x = 0; x < ThreadCount; ++x) { - QVERIFY(thread[x].wait(1000)); - } - } + { + QMutex mutex; + QWaitCondition cond; + + mutex.lock(); + + cond.wakeOne(); + QVERIFY(!cond.wait(&mutex, 1)); + + cond.wakeAll(); + QVERIFY(!cond.wait(&mutex, 1)); + + mutex.unlock(); + } + + { + // test multiple threads waiting on separate wait conditions + wait_QMutex_Thread_1 thread[ThreadCount]; + + for (x = 0; x < ThreadCount; ++x) { + thread[x].mutex.lock(); + thread[x].start(); + // wait for thread to start + QVERIFY(thread[x].cond.wait(&thread[x].mutex, 1000)); + thread[x].mutex.unlock(); + } + + for (x = 0; x < ThreadCount; ++x) { + QVERIFY(thread[x].isRunning()); + QVERIFY(!thread[x].isFinished()); + } + + for (x = 0; x < ThreadCount; ++x) { + thread[x].mutex.lock(); + thread[x].cond.wakeOne(); + thread[x].mutex.unlock(); + } + + for (x = 0; x < ThreadCount; ++x) { + QVERIFY(thread[x].wait(1000)); + } + } + + { + // test multiple threads waiting on a wait condition + QMutex mutex; + QWaitCondition cond1, cond2; + wait_QMutex_Thread_2 thread[ThreadCount]; + + mutex.lock(); + for (x = 0; x < ThreadCount; ++x) { + thread[x].mutex = &mutex; + thread[x].cond = (x < ThreadCount / 2) ? &cond1 : &cond2; + thread[x].start(); + // wait for thread to start + QVERIFY(thread[x].started.wait(&mutex, 1000)); + } + mutex.unlock(); + + for (x = 0; x < ThreadCount; ++x) { + QVERIFY(thread[x].isRunning()); + QVERIFY(!thread[x].isFinished()); + } + + mutex.lock(); + cond1.wakeAll(); + cond2.wakeAll(); + mutex.unlock(); + + for (x = 0; x < ThreadCount; ++x) { + QVERIFY(thread[x].wait(1000)); + } + } } } @@ -282,94 +288,99 @@ void tst_QWaitCondition::wait_QReadWriteLock() int x; for (int i = 0; i < iterations; ++i) { - { - QReadWriteLock readWriteLock; - QWaitCondition waitCondition; - - readWriteLock.lockForRead(); - - waitCondition.wakeOne(); - QVERIFY(!waitCondition.wait(&readWriteLock, 1)); - - waitCondition.wakeAll(); - QVERIFY(!waitCondition.wait(&readWriteLock, 1)); - - readWriteLock.unlock(); - } - - { - QReadWriteLock readWriteLock; - QWaitCondition waitCondition; - - readWriteLock.lockForWrite(); - - waitCondition.wakeOne(); - QVERIFY(!waitCondition.wait(&readWriteLock, 1)); - - waitCondition.wakeAll(); - QVERIFY(!waitCondition.wait(&readWriteLock, 1)); - - readWriteLock.unlock(); - } - - { - // test multiple threads waiting on separate wait conditions - wait_QReadWriteLock_Thread_1 thread[ThreadCount]; - - for (x = 0; x < ThreadCount; ++x) { - thread[x].readWriteLock.lockForRead(); - thread[x].start(); - // wait for thread to start - QVERIFY(thread[x].cond.wait(&thread[x].readWriteLock, 1000)); - thread[x].readWriteLock.unlock(); - } - - for (x = 0; x < ThreadCount; ++x) { - QVERIFY(thread[x].isRunning()); - QVERIFY(!thread[x].isFinished()); - } - - for (x = 0; x < ThreadCount; ++x) { - thread[x].readWriteLock.lockForRead(); - thread[x].cond.wakeOne(); - thread[x].readWriteLock.unlock(); - } - - for (x = 0; x < ThreadCount; ++x) { - QVERIFY(thread[x].wait(1000)); - } - } - - { - // test multiple threads waiting on a wait condition - QReadWriteLock readWriteLock; - QWaitCondition cond1, cond2; - wait_QReadWriteLock_Thread_2 thread[ThreadCount]; - - readWriteLock.lockForWrite(); - for (x = 0; x < ThreadCount; ++x) { - thread[x].readWriteLock = &readWriteLock; - thread[x].cond = (x < ThreadCount / 2) ? &cond1 : &cond2; - thread[x].start(); - // wait for thread to start - QVERIFY(thread[x].started.wait(&readWriteLock, 1000)); - } - readWriteLock.unlock(); - - for (x = 0; x < ThreadCount; ++x) { - QVERIFY(thread[x].isRunning()); - QVERIFY(!thread[x].isFinished()); - } - - readWriteLock.lockForWrite(); - cond1.wakeAll(); - cond2.wakeAll(); - readWriteLock.unlock(); - - for (x = 0; x < ThreadCount; ++x) { - QVERIFY(thread[x].wait(1000)); - } - } + { + QReadWriteLock readWriteLock; + QWaitCondition waitCondition; + + readWriteLock.lockForRead(); + + waitCondition.wakeOne(); + QVERIFY(!waitCondition.wait(&readWriteLock, 1)); + + waitCondition.wakeAll(); + QVERIFY(!waitCondition.wait(&readWriteLock, 1)); + + readWriteLock.unlock(); + } + + { + QReadWriteLock readWriteLock; + QWaitCondition waitCondition; + + readWriteLock.lockForWrite(); + + waitCondition.wakeOne(); + QVERIFY(!waitCondition.wait(&readWriteLock, 1)); + + waitCondition.wakeAll(); + QVERIFY(!waitCondition.wait(&readWriteLock, 1)); + + readWriteLock.unlock(); + } + + { + // test multiple threads waiting on separate wait conditions + wait_QReadWriteLock_Thread_1 thread[ThreadCount]; + + for (x = 0; x < ThreadCount; ++x) { + thread[x].readWriteLock.lockForRead(); + thread[x].start(); + // wait for thread to start +#if defined(Q_OS_SYMBIAN) && defined(Q_CC_WINSCW) + // Symbian emulator startup simultaneously with this thread causes additional delay + QVERIFY(thread[x].cond.wait(&thread[x].readWriteLock, 10000)); +#else + QVERIFY(thread[x].cond.wait(&thread[x].readWriteLock, 1000)); +#endif + thread[x].readWriteLock.unlock(); + } + + for (x = 0; x < ThreadCount; ++x) { + QVERIFY(thread[x].isRunning()); + QVERIFY(!thread[x].isFinished()); + } + + for (x = 0; x < ThreadCount; ++x) { + thread[x].readWriteLock.lockForRead(); + thread[x].cond.wakeOne(); + thread[x].readWriteLock.unlock(); + } + + for (x = 0; x < ThreadCount; ++x) { + QVERIFY(thread[x].wait(1000)); + } + } + + { + // test multiple threads waiting on a wait condition + QReadWriteLock readWriteLock; + QWaitCondition cond1, cond2; + wait_QReadWriteLock_Thread_2 thread[ThreadCount]; + + readWriteLock.lockForWrite(); + for (x = 0; x < ThreadCount; ++x) { + thread[x].readWriteLock = &readWriteLock; + thread[x].cond = (x < ThreadCount / 2) ? &cond1 : &cond2; + thread[x].start(); + // wait for thread to start + QVERIFY(thread[x].started.wait(&readWriteLock, 1000)); + } + readWriteLock.unlock(); + + for (x = 0; x < ThreadCount; ++x) { + QVERIFY(thread[x].isRunning()); + QVERIFY(!thread[x].isFinished()); + } + + readWriteLock.lockForWrite(); + cond1.wakeAll(); + cond2.wakeAll(); + readWriteLock.unlock(); + + for (x = 0; x < ThreadCount; ++x) { + QVERIFY(thread[x].wait(1000)); + } + } } } @@ -386,7 +397,7 @@ public: QWaitCondition *cond; inline wake_Thread() - : mutex(0), cond(0) + : mutex(0), cond(0) { } static inline void sleep(ulong s) @@ -394,14 +405,14 @@ public: void run() { - mutex->lock(); - ++count; + mutex->lock(); + ++count; dummy.wakeOne(); // this wakeup should be lost - started.wakeOne(); + started.wakeOne(); dummy.wakeAll(); // this one too - cond->wait(mutex); + cond->wait(mutex); --count; - mutex->unlock(); + mutex->unlock(); } }; @@ -419,7 +430,7 @@ public: QWaitCondition *cond; inline wake_Thread_2() - : readWriteLock(0), cond(0) + : readWriteLock(0), cond(0) { } static inline void sleep(ulong s) @@ -427,14 +438,14 @@ public: void run() { - readWriteLock->lockForWrite(); - ++count; + readWriteLock->lockForWrite(); + ++count; dummy.wakeOne(); // this wakeup should be lost started.wakeOne(); dummy.wakeAll(); // this one too - cond->wait(readWriteLock); + cond->wait(readWriteLock); --count; - readWriteLock->unlock(); + readWriteLock->unlock(); } }; @@ -445,194 +456,194 @@ void tst_QWaitCondition::wakeOne() int x; // wake up threads, one at a time for (int i = 0; i < iterations; ++i) { - QMutex mutex; - QWaitCondition cond; + QMutex mutex; + QWaitCondition cond; - // QMutex - wake_Thread thread[ThreadCount]; - bool thread_exited[ThreadCount]; - - mutex.lock(); - for (x = 0; x < ThreadCount; ++x) { - thread[x].mutex = &mutex; - thread[x].cond = &cond; - thread_exited[x] = FALSE; - thread[x].start(); - // wait for thread to start - QVERIFY(thread[x].started.wait(&mutex, 1000)); - // make sure wakeups are not queued... if nothing is - // waiting at the time of the wakeup, nothing happens - QVERIFY(!thread[x].dummy.wait(&mutex, 1)); - } - mutex.unlock(); - - QCOMPARE(wake_Thread::count, ThreadCount); - - // wake up threads one at a time - for (x = 0; x < ThreadCount; ++x) { - mutex.lock(); - cond.wakeOne(); - QVERIFY(!cond.wait(&mutex, 1)); - QVERIFY(!thread[x].dummy.wait(&mutex, 1)); - mutex.unlock(); - - int exited = 0; - for (int y = 0; y < ThreadCount; ++y) { - if (thread_exited[y]) - continue; - if (thread[y].wait(exited > 0 ? 1 : 1000)) { - thread_exited[y] = TRUE; - ++exited; - } - } - - QCOMPARE(exited, 1); - QCOMPARE(wake_Thread::count, ThreadCount - (x + 1)); - } - - QCOMPARE(wake_Thread::count, 0); + // QMutex + wake_Thread thread[ThreadCount]; + bool thread_exited[ThreadCount]; + + mutex.lock(); + for (x = 0; x < ThreadCount; ++x) { + thread[x].mutex = &mutex; + thread[x].cond = &cond; + thread_exited[x] = FALSE; + thread[x].start(); + // wait for thread to start + QVERIFY(thread[x].started.wait(&mutex, 1000)); + // make sure wakeups are not queued... if nothing is + // waiting at the time of the wakeup, nothing happens + QVERIFY(!thread[x].dummy.wait(&mutex, 1)); + } + mutex.unlock(); - // QReadWriteLock - QReadWriteLock readWriteLock; - wake_Thread_2 rwthread[ThreadCount]; + QCOMPARE(wake_Thread::count, ThreadCount); + // wake up threads one at a time + for (x = 0; x < ThreadCount; ++x) { + mutex.lock(); + cond.wakeOne(); + QVERIFY(!cond.wait(&mutex, COND_WAIT_TIME)); + QVERIFY(!thread[x].dummy.wait(&mutex, 1)); + mutex.unlock(); + + int exited = 0; + for (int y = 0; y < ThreadCount; ++y) { + if (thread_exited[y]) + continue; + if (thread[y].wait(exited > 0 ? 1 : 1000)) { + thread_exited[y] = TRUE; + ++exited; + } + } + + QCOMPARE(exited, 1); + QCOMPARE(wake_Thread::count, ThreadCount - (x + 1)); + } + + QCOMPARE(wake_Thread::count, 0); + + // QReadWriteLock + QReadWriteLock readWriteLock; + wake_Thread_2 rwthread[ThreadCount]; + + readWriteLock.lockForWrite(); + for (x = 0; x < ThreadCount; ++x) { + rwthread[x].readWriteLock = &readWriteLock; + rwthread[x].cond = &cond; + thread_exited[x] = FALSE; + rwthread[x].start(); + // wait for thread to start + QVERIFY(rwthread[x].started.wait(&readWriteLock, 1000)); + // make sure wakeups are not queued... if nothing is + // waiting at the time of the wakeup, nothing happens + QVERIFY(!rwthread[x].dummy.wait(&readWriteLock, 1)); + } + readWriteLock.unlock(); + + QCOMPARE(wake_Thread_2::count, ThreadCount); + + // wake up threads one at a time + for (x = 0; x < ThreadCount; ++x) { readWriteLock.lockForWrite(); - for (x = 0; x < ThreadCount; ++x) { - rwthread[x].readWriteLock = &readWriteLock; - rwthread[x].cond = &cond; - thread_exited[x] = FALSE; - rwthread[x].start(); - // wait for thread to start - QVERIFY(rwthread[x].started.wait(&readWriteLock, 1000)); - // make sure wakeups are not queued... if nothing is - // waiting at the time of the wakeup, nothing happens - QVERIFY(!rwthread[x].dummy.wait(&readWriteLock, 1)); - } - readWriteLock.unlock(); - - QCOMPARE(wake_Thread_2::count, ThreadCount); - - // wake up threads one at a time - for (x = 0; x < ThreadCount; ++x) { - readWriteLock.lockForWrite(); - cond.wakeOne(); - QVERIFY(!cond.wait(&readWriteLock, 1)); - QVERIFY(!rwthread[x].dummy.wait(&readWriteLock, 1)); - readWriteLock.unlock(); - - int exited = 0; - for (int y = 0; y < ThreadCount; ++y) { - if (thread_exited[y]) - continue; - if (rwthread[y].wait(exited > 0 ? 1 : 1000)) { - thread_exited[y] = TRUE; - ++exited; - } - } - - QCOMPARE(exited, 1); - QCOMPARE(wake_Thread_2::count, ThreadCount - (x + 1)); - } - - QCOMPARE(wake_Thread_2::count, 0); + cond.wakeOne(); + QVERIFY(!cond.wait(&readWriteLock, COND_WAIT_TIME)); + QVERIFY(!rwthread[x].dummy.wait(&readWriteLock, 1)); + readWriteLock.unlock(); + + int exited = 0; + for (int y = 0; y < ThreadCount; ++y) { + if (thread_exited[y]) + continue; + if (rwthread[y].wait(exited > 0 ? 1 : 1000)) { + thread_exited[y] = TRUE; + ++exited; + } + } + + QCOMPARE(exited, 1); + QCOMPARE(wake_Thread_2::count, ThreadCount - (x + 1)); + } + + QCOMPARE(wake_Thread_2::count, 0); } // wake up threads, two at a time for (int i = 0; i < iterations; ++i) { - QMutex mutex; - QWaitCondition cond; + QMutex mutex; + QWaitCondition cond; // QMutex - wake_Thread thread[ThreadCount]; - bool thread_exited[ThreadCount]; - - mutex.lock(); - for (x = 0; x < ThreadCount; ++x) { - thread[x].mutex = &mutex; - thread[x].cond = &cond; - thread_exited[x] = FALSE; - thread[x].start(); - // wait for thread to start - QVERIFY(thread[x].started.wait(&mutex, 1000)); - // make sure wakeups are not queued... if nothing is - // waiting at the time of the wakeup, nothing happens - QVERIFY(!thread[x].dummy.wait(&mutex, 1)); - } - mutex.unlock(); - - QCOMPARE(wake_Thread::count, ThreadCount); - - // wake up threads one at a time - for (x = 0; x < ThreadCount; x += 2) { - mutex.lock(); - cond.wakeOne(); - cond.wakeOne(); - QVERIFY(!cond.wait(&mutex, 1)); - QVERIFY(!thread[x].dummy.wait(&mutex, 1)); - QVERIFY(!thread[x + 1].dummy.wait(&mutex, 1)); - mutex.unlock(); - - int exited = 0; - for (int y = 0; y < ThreadCount; ++y) { - if (thread_exited[y]) - continue; - if (thread[y].wait(exited > 0 ? 1 : 1000)) { - thread_exited[y] = TRUE; - ++exited; - } - } - - QCOMPARE(exited, 2); - QCOMPARE(wake_Thread::count, ThreadCount - (x + 2)); - } - - QCOMPARE(wake_Thread::count, 0); + wake_Thread thread[ThreadCount]; + bool thread_exited[ThreadCount]; + + mutex.lock(); + for (x = 0; x < ThreadCount; ++x) { + thread[x].mutex = &mutex; + thread[x].cond = &cond; + thread_exited[x] = FALSE; + thread[x].start(); + // wait for thread to start + QVERIFY(thread[x].started.wait(&mutex, 1000)); + // make sure wakeups are not queued... if nothing is + // waiting at the time of the wakeup, nothing happens + QVERIFY(!thread[x].dummy.wait(&mutex, 1)); + } + mutex.unlock(); + + QCOMPARE(wake_Thread::count, ThreadCount); + + // wake up threads one at a time + for (x = 0; x < ThreadCount; x += 2) { + mutex.lock(); + cond.wakeOne(); + cond.wakeOne(); + QVERIFY(!cond.wait(&mutex, COND_WAIT_TIME)); + QVERIFY(!thread[x].dummy.wait(&mutex, 1)); + QVERIFY(!thread[x + 1].dummy.wait(&mutex, 1)); + mutex.unlock(); + + int exited = 0; + for (int y = 0; y < ThreadCount; ++y) { + if (thread_exited[y]) + continue; + if (thread[y].wait(exited > 0 ? 1 : 1000)) { + thread_exited[y] = TRUE; + ++exited; + } + } + + QCOMPARE(exited, 2); + QCOMPARE(wake_Thread::count, ThreadCount - (x + 2)); + } + + QCOMPARE(wake_Thread::count, 0); // QReadWriteLock QReadWriteLock readWriteLock; wake_Thread_2 rwthread[ThreadCount]; - readWriteLock.lockForWrite(); - for (x = 0; x < ThreadCount; ++x) { - rwthread[x].readWriteLock = &readWriteLock; - rwthread[x].cond = &cond; - thread_exited[x] = FALSE; - rwthread[x].start(); - // wait for thread to start - QVERIFY(rwthread[x].started.wait(&readWriteLock, 1000)); - // make sure wakeups are not queued... if nothing is - // waiting at the time of the wakeup, nothing happens - QVERIFY(!rwthread[x].dummy.wait(&readWriteLock, 1)); - } - readWriteLock.unlock(); - - QCOMPARE(wake_Thread_2::count, ThreadCount); - - // wake up threads one at a time - for (x = 0; x < ThreadCount; x += 2) { - readWriteLock.lockForWrite(); - cond.wakeOne(); - cond.wakeOne(); - QVERIFY(!cond.wait(&readWriteLock, 1)); - QVERIFY(!rwthread[x].dummy.wait(&readWriteLock, 1)); - QVERIFY(!rwthread[x + 1].dummy.wait(&readWriteLock, 1)); - readWriteLock.unlock(); - - int exited = 0; - for (int y = 0; y < ThreadCount; ++y) { - if (thread_exited[y]) - continue; - if (rwthread[y].wait(exited > 0 ? 1 : 1000)) { - thread_exited[y] = TRUE; - ++exited; - } - } - - QCOMPARE(exited, 2); - QCOMPARE(wake_Thread_2::count, ThreadCount - (x + 2)); - } - - QCOMPARE(wake_Thread_2::count, 0); + readWriteLock.lockForWrite(); + for (x = 0; x < ThreadCount; ++x) { + rwthread[x].readWriteLock = &readWriteLock; + rwthread[x].cond = &cond; + thread_exited[x] = FALSE; + rwthread[x].start(); + // wait for thread to start + QVERIFY(rwthread[x].started.wait(&readWriteLock, 1000)); + // make sure wakeups are not queued... if nothing is + // waiting at the time of the wakeup, nothing happens + QVERIFY(!rwthread[x].dummy.wait(&readWriteLock, 1)); + } + readWriteLock.unlock(); + + QCOMPARE(wake_Thread_2::count, ThreadCount); + + // wake up threads one at a time + for (x = 0; x < ThreadCount; x += 2) { + readWriteLock.lockForWrite(); + cond.wakeOne(); + cond.wakeOne(); + QVERIFY(!cond.wait(&readWriteLock, COND_WAIT_TIME)); + QVERIFY(!rwthread[x].dummy.wait(&readWriteLock, 1)); + QVERIFY(!rwthread[x + 1].dummy.wait(&readWriteLock, 1)); + readWriteLock.unlock(); + + int exited = 0; + for (int y = 0; y < ThreadCount; ++y) { + if (thread_exited[y]) + continue; + if (rwthread[y].wait(exited > 0 ? 1 : 1000)) { + thread_exited[y] = TRUE; + ++exited; + } + } + + QCOMPARE(exited, 2); + QCOMPARE(wake_Thread_2::count, ThreadCount - (x + 2)); + } + + QCOMPARE(wake_Thread_2::count, 0); } } @@ -640,69 +651,69 @@ void tst_QWaitCondition::wakeAll() { int x; for (int i = 0; i < iterations; ++i) { - QMutex mutex; - QWaitCondition cond; + QMutex mutex; + QWaitCondition cond; - // QMutex - wake_Thread thread[ThreadCount]; - - mutex.lock(); - for (x = 0; x < ThreadCount; ++x) { - thread[x].mutex = &mutex; - thread[x].cond = &cond; - thread[x].start(); - // wait for thread to start - QVERIFY(thread[x].started.wait(&mutex, 1000)); - } - mutex.unlock(); - - QCOMPARE(wake_Thread::count, ThreadCount); - - // wake up all threads at once - mutex.lock(); - cond.wakeAll(); - QVERIFY(!cond.wait(&mutex, 1)); - mutex.unlock(); - - int exited = 0; - for (x = 0; x < ThreadCount; ++x) { - if (thread[x].wait(1000)) - ++exited; - } - - QCOMPARE(exited, ThreadCount); - QCOMPARE(wake_Thread::count, 0); + // QMutex + wake_Thread thread[ThreadCount]; - // QReadWriteLock - QReadWriteLock readWriteLock; - wake_Thread_2 rwthread[ThreadCount]; - - readWriteLock.lockForWrite(); - for (x = 0; x < ThreadCount; ++x) { - rwthread[x].readWriteLock = &readWriteLock; - rwthread[x].cond = &cond; - rwthread[x].start(); - // wait for thread to start - QVERIFY(rwthread[x].started.wait(&readWriteLock, 1000)); - } - readWriteLock.unlock(); - - QCOMPARE(wake_Thread_2::count, ThreadCount); - - // wake up all threads at once - readWriteLock.lockForWrite(); - cond.wakeAll(); - QVERIFY(!cond.wait(&readWriteLock, 1)); - readWriteLock.unlock(); - - exited = 0; - for (x = 0; x < ThreadCount; ++x) { - if (rwthread[x].wait(1000)) - ++exited; - } - - QCOMPARE(exited, ThreadCount); - QCOMPARE(wake_Thread_2::count, 0); + mutex.lock(); + for (x = 0; x < ThreadCount; ++x) { + thread[x].mutex = &mutex; + thread[x].cond = &cond; + thread[x].start(); + // wait for thread to start + QVERIFY(thread[x].started.wait(&mutex, 1000)); + } + mutex.unlock(); + + QCOMPARE(wake_Thread::count, ThreadCount); + + // wake up all threads at once + mutex.lock(); + cond.wakeAll(); + QVERIFY(!cond.wait(&mutex, COND_WAIT_TIME)); + mutex.unlock(); + + int exited = 0; + for (x = 0; x < ThreadCount; ++x) { + if (thread[x].wait(1000)) + ++exited; + } + + QCOMPARE(exited, ThreadCount); + QCOMPARE(wake_Thread::count, 0); + + // QReadWriteLock + QReadWriteLock readWriteLock; + wake_Thread_2 rwthread[ThreadCount]; + + readWriteLock.lockForWrite(); + for (x = 0; x < ThreadCount; ++x) { + rwthread[x].readWriteLock = &readWriteLock; + rwthread[x].cond = &cond; + rwthread[x].start(); + // wait for thread to start + QVERIFY(rwthread[x].started.wait(&readWriteLock, 1000)); + } + readWriteLock.unlock(); + + QCOMPARE(wake_Thread_2::count, ThreadCount); + + // wake up all threads at once + readWriteLock.lockForWrite(); + cond.wakeAll(); + QVERIFY(!cond.wait(&readWriteLock, COND_WAIT_TIME)); + readWriteLock.unlock(); + + exited = 0; + for (x = 0; x < ThreadCount; ++x) { + if (rwthread[x].wait(1000)) + ++exited; + } + + QCOMPARE(exited, ThreadCount); + QCOMPARE(wake_Thread_2::count, 0); } } |