コード例 #1
0
 void run()
 {
     mutex->lock();
     ++count;
     dummy.wakeOne(); // this wakeup should be lost
     started.wakeOne();
     dummy.wakeAll(); // this one too
     cond->wait(mutex);
     --count;
     mutex->unlock();
 }
コード例 #2
0
 void run()
 {
     readWriteLock->lockForWrite();
     ++count;
     dummy.wakeOne(); // this wakeup should be lost
     started.wakeOne();
     dummy.wakeAll(); // this one too
     cond->wait(readWriteLock);
     --count;
     readWriteLock->unlock();
 }
コード例 #3
0
 void run()
 {
     readWriteLock.lockForWrite();
     cond.wakeOne();
     cond.wait(&readWriteLock);
     readWriteLock.unlock();
 }
コード例 #4
0
 void run()
 {
     readWriteLock->lockForRead();
     started.wakeOne();
     cond->wait(readWriteLock);
     readWriteLock->unlock();
 }
コード例 #5
0
 void run()
 {
     mutex.lock();
     cond.wakeOne();
     cond.wait(&mutex);
     mutex.unlock();
 }
コード例 #6
0
 void run()
 {
     mutex->lock();
     started.wakeOne();
     cond->wait(mutex);
     mutex->unlock();
 }
コード例 #7
0
    void run()
    {
        pointers.setLocalData(new Pointer);

        QMutexLocker locker(&mutex);
        cond.wakeOne();
        cond.wait(&mutex);
    }
コード例 #8
0
ファイル: userinterface.cpp プロジェクト: baz1/TanxBot
void intSignalHandler(int sig)
{
    Q_UNUSED(sig)
    hIMutex.lock();
    hasInterrupt = true;
    hICondition.wakeOne();
    hIMutex.unlock();
}
コード例 #9
0
ファイル: guiSolvePage.cpp プロジェクト: Drahm/virtualflowlab
void mainWindow::continueSolution (void)
{
   pauseSolveThread = false;
   pauseButton->setEnabled(TRUE);
   continueButton->setEnabled(FALSE);
   continueSolveThread.wakeOne();
   statusLabel->setText(tr("Status: RUNNING"));
}
コード例 #10
0
void
hwcv10_proc_vsync(const struct hwc_procs* procs, int disp, int64_t timestamp)
{
    //fprintf(stderr, "%s: procs=%x, disp=%d, timestamp=%.0f\n", __func__, procs, disp, (float)timestamp);
    vsync_mutex.lock();
    vsync_cond.wakeOne();
    vsync_mutex.unlock();
}
コード例 #11
0
void VS_CC frameDoneCallback(void *userData, const VSFrameRef *f, int n, VSNodeRef *, const char *errorMsg) {
    completedFrames++;

    if (f) {
        reorderMap.insert(n, f);
        while (reorderMap.contains(outputFrames)) {
            const VSFrameRef *frame = reorderMap.take(outputFrames);
            if (!outputError) {
				if (y4m) {
					if (!fwrite("FRAME\n", 6, 1, outFile)) {
						errorMessage = "Error: fwrite() call failed";
						totalFrames = requestedFrames;
						outputError = true;
					}
				}

				if (!outputError) {
					const VSFormat *fi = vsapi->getFrameFormat(frame);
					for (int p = 0; p < fi->numPlanes; p++) {
						int stride = vsapi->getStride(frame, p);
						const uint8_t *readPtr = vsapi->getReadPtr(frame, p);
						int rowSize = vsapi->getFrameWidth(frame, p) * fi->bytesPerSample;
						int height = vsapi->getFrameHeight(frame, p);
						for (int y = 0; y < height; y++) {
							if (!fwrite(readPtr, rowSize, 1, outFile)) {
								errorMessage = "Error: fwrite() call failed";
								totalFrames = requestedFrames;
								outputError = true;
								p = 100; // break out of the outer loop
								break;
							}
							readPtr += stride;
						}
					}
				}
			}
            vsapi->freeFrame(frame);
            outputFrames++;
        }
    } else {
        outputError = true;
        totalFrames = requestedFrames;
        if (errorMsg)
            errorMessage = QString("Error: Failed to retrieve frame ") + n + QString(" with error: ") + QString::fromUtf8(errorMsg);
        else
            errorMessage = QString("Error: Failed to retrieve frame ") + n;
    }

    if (requestedFrames < totalFrames) {
        vsapi->getFrameAsync(requestedFrames, node, frameDoneCallback, NULL);
        requestedFrames++;
    }

    if (totalFrames == completedFrames) {
        QMutexLocker lock(&mutex);
        condition.wakeOne();
    }
}
コード例 #12
0
ファイル: rawhid.cpp プロジェクト: Liambeguin/TauLabs
int RawHIDWriteThread::pushDataToWrite(const char *data, int size)
{
    QMutexLocker lock(&m_writeBufMtx);

    m_writeBuffer.append(data, size);
    m_newDataToWrite.wakeOne(); //signal that new data arrived

    return size;
}
コード例 #13
0
ファイル: IdThreadWorker.cpp プロジェクト: ehaas/tomahawk
void
IdThreadWorker::stop()
{
    {
        QMutexLocker l( &s_mutex );
        m_stop = true;
    }

    s_waitCond.wakeOne();
}
コード例 #14
0
    void run() {
        readWriteLock->lockForWrite();

        ready = true;
        startup->wakeOne();

        returnValue = waitCondition->wait(readWriteLock, timeout);

        readWriteLock->unlock();
    }
コード例 #15
0
    void run() {
        mutex->lock();

        ready = true;
        startup->wakeOne();

        returnValue = waitCondition->wait(mutex, timeout);

        mutex->unlock();
    }
コード例 #16
0
ファイル: FileSystemModel.cpp プロジェクト: gobomus/Natron
 bool checkForExit()
 {
     QMutexLocker l(&mustQuitMutex);
     if (mustQuit) {
         mustQuit = false;
         mustQuitCond.wakeOne();
         return true;
     }
     return false;
 }
コード例 #17
0
ファイル: userinterface.cpp プロジェクト: baz1/TanxBot
void UserInterface::abort()
{
    if (isRunning())
    {
        hIMutex.lock();
        isAborting = true;
        hasInterrupt = true;
        hICondition.wakeOne();
        hIMutex.unlock();
    }
}
コード例 #18
0
ファイル: main.cpp プロジェクト: AdrianoRuberto/Labo-S4
    /**
     * @brief rajoute un vélo sur le site, si auncune borne n'est disponnible
     *        attends qu'une borne se libère
     */
    void put(){
        mutex.lock();

        while(_nbBikes >= NB_BORNES){
            availableBorne.wait(&mutex);
        }
        ++_nbBikes;
        availableBike.wakeOne();
        gui_interface->setBikes(ID, _nbBikes);

        mutex.unlock();
    }
コード例 #19
0
ファイル: FileSystemModel.cpp プロジェクト: gobomus/Natron
 bool checkForAbort()
 {
     
     QMutexLocker k(&abortRequestsMutex);
     if (abortRequests > 0) {
         abortRequests = 0;
         abortRequestsCond.wakeOne();
         return true;
     }
     return false;
     
 }
コード例 #20
0
ファイル: main.cpp プロジェクト: AdrianoRuberto/Labo-S4
    /**
     * @brief enlève un vélo du site, si aucun vélo n'est disponible, attends
     *        que quelqu'un en dépose un
     */
    void take() {
        mutex.lock();

        while(_nbBikes <= 0){
            availableBike.wait(&mutex);
        }
        --_nbBikes;
        availableBorne.wakeOne();
        gui_interface->setBikes(ID, _nbBikes);

        mutex.unlock();
    }
コード例 #21
0
    void run()
    {
        test_mutex.lock();

        mutex.lock();
        for (int i = 0; i < iterations; ++i) {
            cond.wakeOne();
            cond.wait(&mutex);
        }
        mutex.unlock();

        test_mutex.unlock();
    }
コード例 #22
0
ファイル: worker1.cpp プロジェクト: kfengbest/QtThreads
void Consumer1::run()
{
    qDebug() << "Consumer " << m_id << " before wakeall ";

    if(m_bWakeAll)
        g_con.wakeAll();
    else
        g_con.wakeOne();

    qDebug() << "Consumer " << m_id << " after wakeall";


}
コード例 #23
0
ファイル: IdThreadWorker.cpp プロジェクト: ehaas/tomahawk
void
IdThreadWorker::getAlbumId( const album_ptr& album, bool autoCreate )
{
    QueueItem* item = internalGet( artist_ptr(), album, trackdata_ptr(), autoCreate, AlbumType );
    album->setIdFuture( item->promise.future() );

#if ID_THREAD_DEBUG
    tDebug() << "QUEUEING ALUBM:" << album->artist()->name() << album->name();
#endif
    s_mutex.lock();
    s_workQueue.enqueue( item );
    s_mutex.unlock();
    s_waitCond.wakeOne();
#if ID_THREAD_DEBUG
    tDebug() << "DONE WOKE UP THREAD:" << album->artist()->name() << album->name();
#endif
}
コード例 #24
0
ファイル: IdThreadWorker.cpp プロジェクト: ehaas/tomahawk
void
IdThreadWorker::getTrackId( const trackdata_ptr& track, bool autoCreate )
{
    QueueItem* item = internalGet( artist_ptr(), album_ptr(), track, autoCreate, TrackType );
    track->setIdFuture( item->promise.future() );

    #if ID_THREAD_DEBUG
    tDebug() << "QUEUEING TRACK:" << track->toString();
    #endif
    s_mutex.lock();
    s_workQueue.enqueue( item );
    s_mutex.unlock();
    s_waitCond.wakeOne();
    #if ID_THREAD_DEBUG
    tDebug() << "DONE WOKE UP THREAD:" << track->toString();
    #endif
}
コード例 #25
0
void tst_QWaitCondition::wait_QReadWriteLock()
{
    {
        QReadWriteLock readWriteLock(QReadWriteLock::Recursive);
        QWaitCondition waitCondition;

        // ensure that the lockForRead is correctly restored
        readWriteLock.lockForRead();

        QVERIFY(!waitCondition.wait(&readWriteLock, 1));

        QVERIFY(!readWriteLock.tryLockForWrite());
        QVERIFY(readWriteLock.tryLockForRead());
        readWriteLock.unlock();
        QVERIFY(!readWriteLock.tryLockForWrite());
        readWriteLock.unlock();

        QVERIFY(readWriteLock.tryLockForWrite());
        readWriteLock.unlock();
    }

    {
        QReadWriteLock readWriteLock(QReadWriteLock::Recursive);
        QWaitCondition waitCondition;

        // ensure that the lockForWrite is correctly restored
        readWriteLock.lockForWrite();

        QVERIFY(!waitCondition.wait(&readWriteLock, 1));

        QVERIFY(!readWriteLock.tryLockForRead());
        QVERIFY(readWriteLock.tryLockForWrite());
        readWriteLock.unlock();
        QVERIFY(!readWriteLock.tryLockForRead());
        readWriteLock.unlock();

        QVERIFY(readWriteLock.tryLockForRead());
        readWriteLock.unlock();
    }


    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));
            }
        }
    }
}
コード例 #26
0
void tst_QWaitCondition::wait_RaceCondition()
{
    {
        QMutex mutex;
        QWaitCondition startup;
        QWaitCondition waitCondition;

        wait_RaceConditionThread timeoutThread(&mutex, &startup, &waitCondition, 1000),
            waitingThread1(&mutex, &startup, &waitCondition);

        timeoutThread.start();
        waitingThread1.start();
        mutex.lock();

        // wait for the threads to start up
        while (!timeoutThread.ready
               || !waitingThread1.ready) {
            startup.wait(&mutex);
        }

        QTest::qWait(2000);

        waitCondition.wakeOne();

        mutex.unlock();

        QVERIFY(timeoutThread.wait(5000));
        QVERIFY(!timeoutThread.returnValue);
        QVERIFY(waitingThread1.wait(5000));
        QVERIFY(waitingThread1.returnValue);
    }

    {
        QReadWriteLock readWriteLock;
        QWaitCondition startup;
        QWaitCondition waitCondition;

        wait_RaceConditionThread_2 timeoutThread(&readWriteLock, &startup, &waitCondition, 1000),
            waitingThread1(&readWriteLock, &startup, &waitCondition);

        timeoutThread.start();
        waitingThread1.start();
        readWriteLock.lockForRead();

        // wait for the threads to start up
        while (!timeoutThread.ready
               || !waitingThread1.ready) {
            startup.wait(&readWriteLock);
        }

        QTest::qWait(2000);

        waitCondition.wakeOne();

        readWriteLock.unlock();

        QVERIFY(timeoutThread.wait(5000));
        QVERIFY(!timeoutThread.returnValue);
        QVERIFY(waitingThread1.wait(5000));
        QVERIFY(waitingThread1.returnValue);
    }
}
コード例 #27
0
void tst_QWaitCondition::wait_QReadWriteLock()
{
    {
        QReadWriteLock readWriteLock(QReadWriteLock::Recursive);
        QWaitCondition waitCondition;

        // ensure that the lockForRead is correctly restored
        readWriteLock.lockForRead();

        QVERIFY(!waitCondition.wait(&readWriteLock, 1));

        QVERIFY(!readWriteLock.tryLockForWrite());
        QVERIFY(readWriteLock.tryLockForRead());
        readWriteLock.unlock();
        QVERIFY(!readWriteLock.tryLockForWrite());
        readWriteLock.unlock();

        QVERIFY(readWriteLock.tryLockForWrite());
        readWriteLock.unlock();
    }

    {
        QReadWriteLock readWriteLock(QReadWriteLock::Recursive);
        QWaitCondition waitCondition;

        // ensure that the lockForWrite is correctly restored
        readWriteLock.lockForWrite();

        QVERIFY(!waitCondition.wait(&readWriteLock, 1));

        QVERIFY(!readWriteLock.tryLockForRead());
        QVERIFY(readWriteLock.tryLockForWrite());
        readWriteLock.unlock();
        QVERIFY(!readWriteLock.tryLockForRead());
        readWriteLock.unlock();

        QVERIFY(readWriteLock.tryLockForRead());
        readWriteLock.unlock();
    }


    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
#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));
        }
    }
    }

}
コード例 #28
0
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));
            }
        }
    }
}
コード例 #29
0
 void run()
 {
     QMutexLocker locker(&mutex);
     cond.wakeOne();
 }
コード例 #30
0
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
        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, 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 ? 10 : 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();
            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 ? 10 : 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
        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 ? 10 : 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, 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 ? 10 : 1000)) {
                    thread_exited[y] = true;
                    ++exited;
                }
            }

            QCOMPARE(exited, 2);
            QCOMPARE(wake_Thread_2::count, ThreadCount - (x + 2));
        }

        QCOMPARE(wake_Thread_2::count, 0);
    }
}