QByteArray readData() { lock.lockForRead(); ... lock.unlock(); return data; }
unsigned int Album::id() const { Q_D( const Album ); s_idMutex.lockForRead(); const bool waiting = d->waitingForId; unsigned int finalId = d->id; s_idMutex.unlock(); if ( waiting ) { finalId = d->idFuture.result(); s_idMutex.lockForWrite(); d->id = finalId; d->waitingForId = false; if ( d->id > 0 ) s_albumsById.insert( d->id, d->ownRef.toStrongRef() ); s_idMutex.unlock(); } return finalId; }
unsigned int TrackData::trackId() const { s_dataidMutex.lockForRead(); const bool waiting = m_waitingForId; unsigned int finalId = m_trackId; s_dataidMutex.unlock(); if ( waiting ) { finalId = m_idFuture.result(); s_dataidMutex.lockForWrite(); m_trackId = finalId; m_waitingForId = false; if ( m_trackId > 0 ) { s_trackDatasById.insert( m_trackId, m_ownRef.toStrongRef() ); } s_dataidMutex.unlock(); } return finalId; }
char *mythdir_readdir(int dirID) { char *result = NULL; LOG(VB_FILE, LOG_DEBUG, LOC + QString("mythdir_readdir(%1)").arg(dirID)); m_dirWrapperLock.lockForRead(); if (m_remotedirs.contains(dirID)) { int pos = m_remotedirPositions[dirID]; if (m_remotedirs[dirID].size() >= (pos+1)) { result = strdup(m_remotedirs[dirID][pos].toLocal8Bit().constData()); pos++; m_remotedirPositions[dirID] = pos; } } else if (m_localdirs.contains(dirID)) { int sz = offsetof(struct dirent, d_name) + FILENAME_MAX + 1; struct dirent *entry = reinterpret_cast<struct dirent*>(calloc(1, sz)); struct dirent *r = NULL; if ((0 == readdir_r(m_localdirs[dirID], entry, &r)) && (NULL != r)) result = strdup(r->d_name); free(entry); }
void run() { readWriteLock->lockForRead(); started.wakeOne(); cond->wait(readWriteLock); readWriteLock->unlock(); }
char *mythdir_readdir(int dirID) { char *result = NULL; LOG(VB_FILE, LOG_DEBUG, LOC + QString("mythdir_readdir(%1)").arg(dirID)); m_dirWrapperLock.lockForRead(); if (m_remotedirs.contains(dirID)) { int pos = m_remotedirPositions[dirID]; if (m_remotedirs[dirID].size() >= (pos+1)) { result = strdup(m_remotedirs[dirID][pos].toLocal8Bit().constData()); pos++; m_remotedirPositions[dirID] = pos; } } else if (m_localdirs.contains(dirID)) { struct dirent *entry = readdir(m_localdirs[dirID]); if (entry) { result = strdup(entry->d_name); } } m_dirWrapperLock.unlock(); return result; }
static void accuracyChanged(JNIEnv * /*env*/, jobject /*thiz*/, jint sensor, jint accuracy) { listenersLocker.lockForRead(); foreach (AndroidSensors::AndroidSensorsListenerInterface *listener, listenersHash[sensor]) listener->onAccuracyChanged(accuracy); listenersLocker.unlock(); }
int mythfile_close(int fileID) { int result = -1; LOG(VB_FILE, LOG_DEBUG, LOC + QString("mythfile_close(%1)").arg(fileID)); m_fileWrapperLock.lockForRead(); if (m_ringbuffers.contains(fileID)) { RingBuffer *rb = m_ringbuffers[fileID]; m_ringbuffers.remove(fileID); delete rb; result = 0; } else if (m_remotefiles.contains(fileID)) { RemoteFile *rf = m_remotefiles[fileID]; m_remotefiles.remove(fileID); delete rf; result = 0; } else if (m_localfiles.contains(fileID)) { close(m_localfiles[fileID]); m_localfiles.remove(fileID); result = 0; } m_fileWrapperLock.unlock(); return result; }
void MainWindow::refreshQueues() { g_queuesLock.lockForRead(); int i; for(i=0;i<g_queues.size();i++) { QTreeWidgetItem* item; if(i>=treeQueues->topLevelItemCount()) { item = new QTreeWidgetItem(treeQueues, QStringList(g_queues[i]->name())); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); treeQueues->addTopLevelItem(item); } else { item = treeQueues->topLevelItem(i); item->setText(0, g_queues[i]->name()); } item->setData(0, Qt::UserRole, qVariantFromValue((void*) g_queues[i])); } while(i<treeQueues->topLevelItemCount()) qDebug() << "Removing item" << i << treeQueues->takeTopLevelItem(i); int upt = 0, downt = 0; int upq = 0, downq = 0; int cur = getSelectedQueue(); for(int j=0;j<g_queues.size();j++) { Queue* q = g_queues[j]; q->lock(); for(int i=0;i<q->size();i++) { int up,down; q->at(i)->speeds(down,up); downt += down; upt += up; if(j == cur) { downq += down; upq += up; } } q->unlock(); } g_queuesLock.unlock(); m_labelStatus.setText( QString(tr("Queue's speed: %1 down, %2 up")).arg(formatSize(downq,true)).arg(formatSize(upq,true)) ); }
void tst_QReadWriteLock::readLockUnlockLoop() { QReadWriteLock rwlock; int runs=10000; int i; for (i=0; i<runs; ++i) { rwlock.lockForRead(); rwlock.unlock(); } }
static void sensorChanged(JNIEnv *env, jobject /*thiz*/, jint sensor, jlong timeStamp, jfloatArray array) { uint size = env->GetArrayLength(array); jfloat *values = env->GetFloatArrayElements(array, 0); listenersLocker.lockForRead(); foreach (AndroidSensors::AndroidSensorsListenerInterface *listener, listenersHash[sensor]) listener->onSensorChanged(timeStamp, values, size); listenersLocker.unlock(); env->ReleaseFloatArrayElements(array, values, JNI_ABORT); // don't copy back the elements }
//! Entrypoint for LogThread //! Check to see if there are things to log and if so, write them to disk. //! Otherwise, wait 100ms and check again. //! Exit only when "go" is false AND all queued events are written void LogThread::run() { while(! actionLog.isEmpty() || go) { while(! actionLog.isEmpty()) { // Write all queued log entries lock.lockForRead(); LogEntry entry = actionLog.dequeue(); lock.unlock(); outStream << entry.dat.asInt << entry.position; ++logEntryCountByServo[entry.dat.asBitfield.servoIndex]; yieldCurrentThread(); } msleep(100); } exit(0); }
int mythfile_stat_fd(int fileID, struct stat *buf) { LOG(VB_FILE, LOG_DEBUG, QString("mythfile_stat_fd(%1, %2)") .arg(fileID).arg((long long)buf)); m_fileWrapperLock.lockForRead(); if (!m_filenames.contains(fileID)) { m_fileWrapperLock.unlock(); return -1; } QString filename = m_filenames[fileID]; m_fileWrapperLock.unlock(); return mythfile_stat(filename.toLocal8Bit().constData(), buf); }
off_t mythfile_tell(int fileID) { off_t result = -1; LOG(VB_FILE, LOG_DEBUG, LOC + QString("mythfile_tell(%1)").arg(fileID)); m_fileWrapperLock.lockForRead(); if (m_ringbuffers.contains(fileID)) result = m_ringbuffers[fileID]->Seek(0, SEEK_CUR); else if (m_remotefiles.contains(fileID)) result = m_remotefiles[fileID]->Seek(0, SEEK_CUR); else if (m_localfiles.contains(fileID)) result = lseek(m_localfiles[fileID], 0, SEEK_CUR); m_fileWrapperLock.unlock(); return result; }
off_t mythfile_seek(int fileID, off_t offset, int whence) { off_t result = -1; LOG(VB_FILE, LOG_DEBUG, LOC + QString("mythfile_seek(%1, %2, %3)") .arg(fileID).arg(offset).arg(whence)); m_fileWrapperLock.lockForRead(); if (m_ringbuffers.contains(fileID)) result = m_ringbuffers[fileID]->Seek(offset, whence); else if (m_remotefiles.contains(fileID)) result = m_remotefiles[fileID]->Seek(offset, whence); else if (m_localfiles.contains(fileID)) result = lseek(m_localfiles[fileID], offset, whence); m_fileWrapperLock.unlock(); return result; }
ssize_t mythfile_write(int fileID, void *buf, size_t count) { ssize_t result = -1; LOG(VB_FILE, LOG_DEBUG, LOC + QString("mythfile_write(%1, %2, %3)") .arg(fileID) .arg((long long)buf).arg(count)); m_fileWrapperLock.lockForRead(); if (m_ringbuffers.contains(fileID)) result = m_ringbuffers[fileID]->Write(buf, count); else if (m_remotefiles.contains(fileID)) result = m_remotefiles[fileID]->Write(buf, count); else if (m_localfiles.contains(fileID)) result = write(m_localfiles[fileID], buf, count); m_fileWrapperLock.unlock(); return result; }
ssize_t mythfile_read(int fileID, void *buf, size_t count) { ssize_t result = -1; VERBOSE(VB_FILE+VB_EXTRA, LOC + QString("mythfile_read(%1, %2, %3)").arg(fileID) .arg((long long)buf).arg(count)); m_fileWrapperLock.lockForRead(); if (m_ringbuffers.contains(fileID)) result = m_ringbuffers[fileID]->Read(buf, count); else if (m_remotefiles.contains(fileID)) result = m_remotefiles[fileID]->Read(buf, count); else if (m_localfiles.contains(fileID)) result = read(m_localfiles[fileID], buf, count); m_fileWrapperLock.unlock(); return result; }
int main(int argc, char** argv) { int i; const int n_threads = 10; std::vector<QThread*> tid(n_threads); s_iterations = argc > 1 ? atoi(argv[1]) : 1000; fprintf(stderr, "Start of test.\n"); { // Stack-allocated reader-writer lock. QReadWriteLock RWL; RWL.lockForRead(); RWL.unlock(); RWL.lockForWrite(); RWL.unlock(); } pthread_barrier_init(&s_barrier, 0, n_threads); s_pRWlock = new QReadWriteLock(); for (i = 0; i < n_threads; i++) { tid[i] = new IncThread; tid[i]->start(); } for (i = 0; i < n_threads; i++) { tid[i]->wait(); delete tid[i]; } delete s_pRWlock; s_pRWlock = 0; pthread_barrier_destroy(&s_barrier); if (s_counter == n_threads * s_iterations) fprintf(stderr, "Test successful.\n"); else fprintf(stderr, "Test failed: counter = %d, should be %d\n", s_counter, n_threads * s_iterations); return 0; }
off_t mythfile_tell(int fileID) { off_t result = -1; VERBOSE(VB_FILE+VB_EXTRA, LOC + QString("mythfile_tell(%1)").arg(fileID)); m_fileWrapperLock.lockForRead(); if (m_ringbuffers.contains(fileID)) result = m_ringbuffers[fileID]->Seek(0, SEEK_CUR); else if (m_remotefiles.contains(fileID)) result = m_remotefiles[fileID]->Seek(0, SEEK_CUR); else if (m_localfiles.contains(fileID)) #ifdef USING_MINGW result = lseek64(m_localfiles[fileID], 0, SEEK_CUR); #else result = lseek(m_localfiles[fileID], 0, SEEK_CUR); #endif m_fileWrapperLock.unlock(); return result; }
off_t mythfile_seek(int fileID, off_t offset, int whence) { off_t result = -1; VERBOSE(VB_FILE+VB_EXTRA, LOC + QString("mythfile_seek(%1, %2, %3)") .arg(fileID).arg(offset).arg(whence)); m_fileWrapperLock.lockForRead(); if (m_ringbuffers.contains(fileID)) result = m_ringbuffers[fileID]->Seek(offset, whence); else if (m_remotefiles.contains(fileID)) result = m_remotefiles[fileID]->Seek(offset, whence); else if (m_localfiles.contains(fileID)) #ifdef USING_MINGW result = lseek64(m_localfiles[fileID], offset, whence); #else result = lseek(m_localfiles[fileID], offset, whence); #endif m_fileWrapperLock.unlock(); return result; }
trackdata_ptr TrackData::get( unsigned int id, const QString& artist, const QString& track ) { s_dataidMutex.lockForRead(); if ( s_trackDatasById.contains( id ) ) { trackdata_wptr track = s_trackDatasById.value( id ); s_dataidMutex.unlock(); if ( track ) return track; } s_dataidMutex.unlock(); QMutexLocker lock( &s_datanameCacheMutex ); const QString key = cacheKey( artist, track ); if ( s_trackDatasByName.contains( key ) ) { trackdata_wptr track = s_trackDatasByName.value( key ); if ( track ) return track; } trackdata_ptr t = trackdata_ptr( new TrackData( id, artist, track ), &TrackData::deleteLater ); t->moveToThread( QCoreApplication::instance()->thread() ); t->setWeakRef( t.toWeakRef() ); s_trackDatasByName.insert( key, t ); if ( id > 0 ) { s_dataidMutex.lockForWrite(); s_trackDatasById.insert( id, t ); s_dataidMutex.unlock(); } else t->loadId( false ); return t; }
QList<QString> RuleList::dnsRequest(QString host) { static QReadWriteLock rwLock; static QMap<QString, QList<QString> > dnsCache; rwLock.lockForRead(); QList<QString> ipsCache=dnsCache[host]; rwLock.unlock(); if(ipsCache.size() > 0) { //qDebug("On a %i ips dans le cache pour l'host '%s'", ipsCache.size(), qPrintable(host)); return ipsCache; } else { QList<QString> ips; struct hostent *s_host; if((s_host = gethostbyname(qPrintable(host)))!=NULL) { struct in_addr **a; for (a=(struct in_addr **)s_host->h_addr_list; *a; a++) { ips.push_back(inet_ntoa(**a)); } // add the ips to the cache rwLock.lockForWrite(); dnsCache[host].clear(); dnsCache[host].append(ips); rwLock.unlock(); } else EventDispatcher::instance().sendCritical(QObject::tr("Error while querying the DNS server(Host='%1')").arg(host)); return ips; } }
static PyObject *meth_QReadWriteLock_lockForRead(PyObject *sipSelf, PyObject *sipArgs) { PyObject *sipParseErr = NULL; { QReadWriteLock *sipCpp; if (sipParseArgs(&sipParseErr, sipArgs, "B", &sipSelf, sipType_QReadWriteLock, &sipCpp)) { Py_BEGIN_ALLOW_THREADS sipCpp->lockForRead(); Py_END_ALLOW_THREADS Py_INCREF(Py_None); return Py_None; } } /* Raise an exception if the arguments couldn't be parsed. */ sipNoMethod(sipParseErr, sipName_QReadWriteLock, sipName_lockForRead, doc_QReadWriteLock_lockForRead); return NULL; }
int mythdir_closedir(int dirID) { int result = -1; LOG(VB_FILE, LOG_DEBUG, LOC + QString("mythdir_closedir(%1)").arg(dirID)); m_dirWrapperLock.lockForRead(); if (m_remotedirs.contains(dirID)) { m_remotedirs.remove(dirID); m_remotedirPositions.remove(dirID); result = 0; } else if (m_localdirs.contains(dirID)) { closedir(m_localdirs[dirID]); m_localdirs.remove(dirID); result = 0; } m_dirWrapperLock.unlock(); return -1; }
bool QueueView::dropMimeData(QTreeWidgetItem* parent, int index, const QMimeData* data, Qt::DropAction action) { if(action == Qt::IgnoreAction) return true; int queueTo = parent->treeWidget()->indexOfTopLevelItem(parent); if(data->hasFormat("application/x-fatrat-transfer")) { g_queuesLock.lockForRead(); QByteArray encodedData = data->data("application/x-fatrat-transfer"); QDataStream stream(&encodedData, QIODevice::ReadOnly); int queueFrom; QList<int> transfers; QList<Transfer*> objects; Queue* q; stream >> queueFrom >> transfers; if(queueFrom != queueTo && queueTo < g_queues.size()) { q = g_queues[queueFrom]; q->lockW(); for(int i=0;i<transfers.size();i++) objects << q->take(transfers[i]-i, true); q->unlock(); q = g_queues[queueTo]; q->add(objects); } g_queuesLock.unlock(); }
album_ptr Album::get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist ) { s_idMutex.lockForRead(); if ( s_albumsById.contains( id ) ) { album_wptr album = s_albumsById.value( id ); s_idMutex.unlock(); if ( album ) return album; } s_idMutex.unlock(); QMutexLocker lock( &s_nameCacheMutex ); const QString key = albumCacheKey( artist, name ); if ( s_albumsByName.contains( key ) ) { album_wptr album = s_albumsByName.value( key ); if ( album ) return album; } album_ptr a = album_ptr( new Album( id, name, artist ), &Album::deleteLater ); a->setWeakRef( a.toWeakRef() ); s_albumsByName.insert( key, a ); if ( id > 0 ) { s_idMutex.lockForWrite(); s_albumsById.insert( id, a ); s_idMutex.unlock(); } return a; }
unsigned int Album::id() const { s_idMutex.lockForRead(); const bool waiting = m_waitingForId; unsigned int finalId = m_id; s_idMutex.unlock(); if ( waiting ) { finalId = m_idFuture.result(); s_idMutex.lockForWrite(); m_id = finalId; m_waitingForId = false; if ( m_id > 0 ) s_albumsById.insert( m_id, m_ownRef.toStrongRef() ); s_idMutex.unlock(); } return finalId; }
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)); } } } }
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); } }
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)); } } } }