int mythdir_opendir(const char *dirname) { LOG(VB_FILE, LOG_DEBUG, LOC + QString("mythdir_opendir(%1)").arg(dirname)); int id = 0; if (strncmp(dirname, "myth://", 7)) { DIR *dir = opendir(dirname); m_dirWrapperLock.lockForWrite(); id = getNextDirID(); m_localdirs[id] = dir; m_dirnames[id] = dirname; m_dirWrapperLock.unlock(); } else { QStringList list; QUrl qurl(dirname); QString storageGroup = qurl.userName(); list.clear(); if (storageGroup.isEmpty()) storageGroup = "Default"; list << "QUERY_SG_GETFILELIST"; list << qurl.host(); list << storageGroup; QString path = qurl.path(); if (!qurl.fragment().isEmpty()) path += "#" + qurl.fragment(); list << path; list << "1"; bool ok = gCoreContext->SendReceiveStringList(list); if ((!ok) || ((list.size() == 1) && (list[0] == "EMPTY LIST"))) list.clear(); m_dirWrapperLock.lockForWrite(); id = getNextDirID(); m_remotedirs[id] = list; m_remotedirPositions[id] = 0; m_dirnames[id] = dirname; m_dirWrapperLock.unlock(); } return id; }
void run() { readWriteLock.lockForWrite(); cond.wakeOne(); cond.wait(&readWriteLock); readWriteLock.unlock(); }
void MainWindow::newQueue() { QueueDlg dlg(this); if(dlg.exec() == QDialog::Accepted) { Queue* q = new Queue; q->setName(dlg.m_strName); q->setSpeedLimits(dlg.m_nDownLimit,dlg.m_nUpLimit); if(dlg.m_bLimit) q->setTransferLimits(dlg.m_nDownTransfersLimit,dlg.m_nUpTransfersLimit); else q->setTransferLimits(-1, -1); q->setUpAsDown(dlg.m_bUpAsDown); q->setDefaultDirectory(dlg.m_strDefaultDirectory); q->setMoveDirectory(dlg.m_strMoveDirectory); g_queuesLock.lockForWrite(); g_queues << q; g_queuesLock.unlock(); Queue::saveQueuesAsync(); refreshQueues(); } }
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; }
void tst_QReadWriteLock::writeLockUnlockLoop() { QReadWriteLock rwlock; int runs=10000; int i; for (i=0; i<runs; ++i) { rwlock.lockForWrite(); rwlock.unlock(); } }
void run() { readWriteLock->lockForWrite(); ready = true; startup->wakeOne(); returnValue = waitCondition->wait(readWriteLock, timeout); readWriteLock->unlock(); }
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(); }
void TonemapperThread::terminateRequested() { if (forciblyTerminated) return; lock.lockForWrite(); pregamma=-1; xsize=-1; lock.unlock(); forciblyTerminated=true; //HACK oddly enough for the other operators we cannot emit finished (it segfaults) if (opts.tmoperator==mantiuk || opts.tmoperator==ashikhmin || opts.tmoperator==pattanaik ) emit finished(); terminate(); }
int mythdir_check(int id) { LOG(VB_FILE, LOG_DEBUG, QString("mythdir_check(%1)").arg(id)); int result = 0; m_dirWrapperLock.lockForWrite(); if (m_localdirs.contains(id)) result = 1; else if (m_remotedirs.contains(id)) result = 1; m_dirWrapperLock.unlock(); return result; }
void tst_QReadWriteLock::writeLockLoop() { /* If you include this, the test should print one line and then block. */ #if 0 QReadWriteLock rwlock; int runs=10000; int i; for (i=0; i<runs; ++i) { rwlock.lockForWrite(); qDebug("I am going to block now."); } #endif }
int mythfile_check(int id) { VERBOSE(VB_FILE+VB_EXTRA, QString("mythfile_check(%1)").arg(id)); int result = 0; m_fileWrapperLock.lockForWrite(); if (m_localfiles.contains(id)) result = 1; else if (m_remotefiles.contains(id)) result = 1; else if (m_ringbuffers.contains(id)) result = 1; 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; }
void tst_QGlobalStatic::threadStressTest() { class ThreadStressTestThread: public QThread { public: QReadWriteLock *lock; void run() { QReadLocker l(lock); //usleep(qrand() * 200 / RAND_MAX); // thundering herd try { threadStressTestGS(); } catch (int) { } } }; ThrowingType::constructedCount.store(0); ThrowingType::destructedCount.store(0); int expectedConstructionCount = threadStressTestControlVar.load() + 1; if (expectedConstructionCount <= 0) QSKIP("This test cannot be run more than once"); const int numThreads = 200; ThreadStressTestThread threads[numThreads]; QReadWriteLock lock; lock.lockForWrite(); for (int i = 0; i < numThreads; ++i) { threads[i].lock = &lock; threads[i].start(); } // wait for all threads // release the herd lock.unlock(); for (int i = 0; i < numThreads; ++i) threads[i].wait(); QCOMPARE(ThrowingType::constructedCount.loadAcquire(), expectedConstructionCount); QCOMPARE(ThrowingType::destructedCount.loadAcquire(), 0); }
void MainWindow::deleteQueue() { int queue; queue = getSelectedQueue(); if(g_queues.empty() || queue < 0) return; if(QMessageBox::warning(this, tr("Delete queue"), tr("Do you really want to delete the active queue?"), QMessageBox::Yes|QMessageBox::No) == QMessageBox::Yes) { g_queuesLock.lockForWrite(); delete g_queues.takeAt(queue); g_queuesLock.unlock(); Queue::saveQueuesAsync(); refreshQueues(); } }
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; } }
void Album::deleteLater() { QMutexLocker lock( &s_nameCacheMutex ); const QString key = albumCacheKey( m_artist, m_name ); if ( s_albumsByName.contains( key ) ) { s_albumsByName.remove( key ); } if ( m_id > 0 ) { s_idMutex.lockForWrite(); if ( s_albumsById.contains( m_id ) ) { s_albumsById.remove( m_id ); } s_idMutex.unlock(); } QObject::deleteLater(); }
void TrackData::deleteLater() { QMutexLocker lock( &s_datanameCacheMutex ); const QString key = cacheKey( m_artist, m_track ); if ( s_trackDatasByName.contains( key ) ) { s_trackDatasByName.remove( key ); } if ( m_trackId > 0 ) { s_dataidMutex.lockForWrite(); if ( s_trackDatasById.contains( m_trackId ) ) { s_trackDatasById.remove( m_trackId ); } s_dataidMutex.unlock(); } QObject::deleteLater(); }
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::wakeAll() { int x; for (int i = 0; i < iterations; ++i) { 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, 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); } }
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); } }
void TonemapperThread::run() { qDebug("TMthread::begin thread, size=%d, gamma=%f",xsize, pregamma); lock.lockForRead(); if (opts.xsize==originalxsize && opts.pregamma==1.0f) { //original goes into tone mapping qDebug("TMthread::original goes into tone mapping"); fetch("/original.pfs"); status=from_tm; colorspaceconversion=true; emit setMaximumSteps(2); } else if (opts.xsize==xsize && opts.pregamma==1.0f) { //resized goes into tone mapping qDebug("TMthread::resized goes into tone mapping"); fetch("/after_resize.pfs"); status=from_tm; colorspaceconversion=true; emit setMaximumSteps(2); } else if ( (opts.xsize==xsize && opts.pregamma==pregamma) || (opts.xsize==originalxsize && xsize==-1 && opts.pregamma==pregamma) ) { //after_pregamma goes into tone mapping qDebug("TMthread::after_pregamma goes into tone mapping"); fetch("/after_pregamma.pfs"); status=from_tm; emit setMaximumSteps(2); } else if (opts.xsize==xsize) { //resized goes into pregamma qDebug("TMthread::resized goes into pregamma"); fetch("/after_resize.pfs"); status=from_pregamma; emit setMaximumSteps(3); } else if (opts.xsize==originalxsize) { //original goes into pregamma qDebug("TMthread::original goes into pregamma"); fetch("/original.pfs"); status=from_pregamma; emit setMaximumSteps(3); } else { //original goes into resize qDebug("TMthread::original goes into resize"); fetch("/original.pfs"); status=from_resize; emit setMaximumSteps(4); } emit advanceCurrentProgress(); lock.unlock(); if (status==from_resize) { assert(opts.xsize!=originalxsize); qDebug("TMthread:: executing resize step"); pfs::Frame *resized=resizeFrame(workingframe, opts.xsize); lock.lockForWrite(); swap(resized,"/after_resize.pfs"); xsize=opts.xsize; pregamma=-1; lock.unlock(); delete workingframe; workingframe=resized; status=from_pregamma; emit advanceCurrentProgress(); } if (status==from_pregamma) { qDebug("TMthread:: executing pregamma step"); applyGammaFrame( workingframe, opts.pregamma ); lock.lockForWrite(); swap(workingframe,"/after_pregamma.pfs"); pregamma=opts.pregamma; if (opts.xsize==originalxsize) xsize=-1; else xsize=opts.xsize; lock.unlock(); status=from_tm; emit advanceCurrentProgress(); } if (status==from_tm) { qDebug("TMthread:: executing tone mapping step"); if (colorspaceconversion) workingframe->convertRGBChannelsToXYZ(); pfs::Frame *result=NULL; switch (opts.tmoperator) { case mantiuk: result=pfstmo_mantiuk06(workingframe, opts.operator_options.mantiukoptions.contrastfactor, opts.operator_options.mantiukoptions.saturationfactor, opts.operator_options.mantiukoptions.detailfactor, opts.operator_options.mantiukoptions.contrastequalization); break; case fattal: //fattal is NOT even reentrant! (problem in PDE solving) //therefore I need to use a mutex here lock.lockForWrite(); result=pfstmo_fattal02(workingframe, opts.operator_options.fattaloptions.alpha, opts.operator_options.fattaloptions.beta, opts.operator_options.fattaloptions.color, opts.operator_options.fattaloptions.noiseredux, opts.operator_options.fattaloptions.newfattal); lock.unlock(); break; case ashikhmin: result=pfstmo_ashikhmin02(workingframe, opts.operator_options.ashikhminoptions.simple, opts.operator_options.ashikhminoptions.lct, opts.operator_options.ashikhminoptions.eq2 ? 2 : 4); break; case durand: //even durand seems to be not reentrant lock.lockForWrite(); result=pfstmo_durand02(workingframe, opts.operator_options.durandoptions.spatial, opts.operator_options.durandoptions.range, opts.operator_options.durandoptions.base); lock.unlock(); break; case drago: result=pfstmo_drago03(workingframe, opts.operator_options.dragooptions.bias); break; case pattanaik: result=pfstmo_pattanaik00(workingframe, opts.operator_options.pattanaikoptions.local, opts.operator_options.pattanaikoptions.multiplier, opts.operator_options.pattanaikoptions.cone, opts.operator_options.pattanaikoptions.rod, opts.operator_options.pattanaikoptions.autolum); break; case reinhard02: result=pfstmo_reinhard02(workingframe, opts.operator_options.reinhard02options.key, opts.operator_options.reinhard02options.phi, opts.operator_options.reinhard02options.range, opts.operator_options.reinhard02options.lower, opts.operator_options.reinhard02options.upper, opts.operator_options.reinhard02options.scales); break; case reinhard05: result=pfstmo_reinhard05(workingframe, opts.operator_options.reinhard05options.brightness, opts.operator_options.reinhard05options.chromaticAdaptation, opts.operator_options.reinhard05options.lightAdaptation); break; } //switch (opts.tmoperator) emit advanceCurrentProgress(); assert(result!=NULL); delete workingframe; const QImage& res=fromLDRPFStoQImage(result); delete result; emit ImageComputed(res,&opts); } //if (status==from_tm) // emit finished(); }
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_QReadWriteLock::writeLockUnlock() { QReadWriteLock rwlock; rwlock.lockForWrite(); rwlock.unlock(); }
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)); } } } }
void tst_QReadWriteLock::tryReadLock() { QReadWriteLock rwlock; QVERIFY(rwlock.tryLockForRead()); rwlock.unlock(); QVERIFY(rwlock.tryLockForRead()); rwlock.unlock(); rwlock.lockForRead(); rwlock.lockForRead(); QVERIFY(rwlock.tryLockForRead()); rwlock.unlock(); rwlock.unlock(); rwlock.unlock(); rwlock.lockForWrite(); QVERIFY(!rwlock.tryLockForRead()); rwlock.unlock(); // functionality test { class Thread : public QThread { public: void run() { testsTurn.release(); threadsTurn.acquire(); QVERIFY(!readWriteLock.tryLockForRead()); testsTurn.release(); threadsTurn.acquire(); QVERIFY(readWriteLock.tryLockForRead()); lockCount.ref(); QVERIFY(readWriteLock.tryLockForRead()); lockCount.ref(); lockCount.deref(); readWriteLock.unlock(); lockCount.deref(); readWriteLock.unlock(); testsTurn.release(); threadsTurn.acquire(); QTime timer; timer.start(); QVERIFY(!readWriteLock.tryLockForRead(1000)); QVERIFY(timer.elapsed() >= 1000); testsTurn.release(); threadsTurn.acquire(); timer.start(); QVERIFY(readWriteLock.tryLockForRead(1000)); QVERIFY(timer.elapsed() <= 1000); lockCount.ref(); QVERIFY(readWriteLock.tryLockForRead(1000)); lockCount.ref(); lockCount.deref(); readWriteLock.unlock(); lockCount.deref(); readWriteLock.unlock(); testsTurn.release(); threadsTurn.acquire(); } }; Thread thread; thread.start(); testsTurn.acquire(); readWriteLock.lockForWrite(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); threadsTurn.release(); testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); readWriteLock.unlock(); threadsTurn.release(); testsTurn.acquire(); readWriteLock.lockForWrite(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); threadsTurn.release(); testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); readWriteLock.unlock(); threadsTurn.release(); // stop thread testsTurn.acquire(); threadsTurn.release(); thread.wait(); } }
void tst_QReadWriteLock::tryWriteLock() { { QReadWriteLock rwlock; QVERIFY(rwlock.tryLockForWrite()); rwlock.unlock(); QVERIFY(rwlock.tryLockForWrite()); rwlock.unlock(); rwlock.lockForWrite(); QVERIFY(!rwlock.tryLockForWrite()); QVERIFY(!rwlock.tryLockForWrite()); rwlock.unlock(); rwlock.lockForRead(); QVERIFY(!rwlock.tryLockForWrite()); rwlock.unlock(); } { QReadWriteLock rwlock(QReadWriteLock::Recursive); QVERIFY(rwlock.tryLockForWrite()); rwlock.unlock(); QVERIFY(rwlock.tryLockForWrite()); rwlock.unlock(); rwlock.lockForWrite(); QVERIFY(rwlock.tryLockForWrite()); QVERIFY(rwlock.tryLockForWrite()); rwlock.unlock(); rwlock.unlock(); rwlock.unlock(); rwlock.lockForRead(); QVERIFY(!rwlock.tryLockForWrite()); rwlock.unlock(); } // functionality test { class Thread : public QThread { public: Thread() : failureCount(0) { } void run() { testsTurn.release(); threadsTurn.acquire(); if (readWriteLock.tryLockForWrite()) failureCount++; testsTurn.release(); threadsTurn.acquire(); if (!readWriteLock.tryLockForWrite()) failureCount++; if (!lockCount.testAndSetRelaxed(0, 1)) failureCount++; if (!lockCount.testAndSetRelaxed(1, 0)) failureCount++; readWriteLock.unlock(); testsTurn.release(); threadsTurn.acquire(); if (readWriteLock.tryLockForWrite(1000)) failureCount++; testsTurn.release(); threadsTurn.acquire(); if (!readWriteLock.tryLockForWrite(1000)) failureCount++; if (!lockCount.testAndSetRelaxed(0, 1)) failureCount++; if (!lockCount.testAndSetRelaxed(1, 0)) failureCount++; readWriteLock.unlock(); testsTurn.release(); threadsTurn.acquire(); } int failureCount; }; Thread thread; thread.start(); testsTurn.acquire(); readWriteLock.lockForRead(); lockCount.ref(); threadsTurn.release(); testsTurn.acquire(); lockCount.deref(); readWriteLock.unlock(); threadsTurn.release(); testsTurn.acquire(); readWriteLock.lockForRead(); lockCount.ref(); threadsTurn.release(); testsTurn.acquire(); lockCount.deref(); readWriteLock.unlock(); threadsTurn.release(); // stop thread testsTurn.acquire(); threadsTurn.release(); thread.wait(); QCOMPARE(thread.failureCount, 0); } }
int mythfile_open(const char *pathname, int flags) { LOG(VB_FILE, LOG_DEBUG, QString("mythfile_open('%1', %2)") .arg(pathname).arg(flags)); struct stat fileinfo; if (mythfile_stat(pathname, &fileinfo)) return -1; if (S_ISDIR( fileinfo.st_mode )) // libmythdvdnav tries to open() a dir return errno = EISDIR, -1; int fileID = -1; if (strncmp(pathname, "myth://", 7)) { int lfd = open(pathname, flags); if (lfd < 0) return -1; m_fileWrapperLock.lockForWrite(); fileID = getNextFileID(); m_localfiles[fileID] = lfd; m_filenames[fileID] = pathname; m_fileWrapperLock.unlock(); } else { RingBuffer *rb = NULL; RemoteFile *rf = NULL; if ((fileinfo.st_size < 512) && (fileinfo.st_mtime < (time(NULL) - 300))) { if (flags & O_WRONLY) rf = new RemoteFile(pathname, true, false); // Writeable else rf = new RemoteFile(pathname, false, true); // Read-Only if (!rf) return -1; } else { if (flags & O_WRONLY) rb = RingBuffer::Create( pathname, true, false, RingBuffer::kDefaultOpenTimeout, true); // Writeable else rb = RingBuffer::Create( pathname, false, true, RingBuffer::kDefaultOpenTimeout, true); // Read-Only if (!rb) return -1; rb->Start(); } m_fileWrapperLock.lockForWrite(); fileID = getNextFileID(); if (rf) m_remotefiles[fileID] = rf; else if (rb) m_ringbuffers[fileID] = rb; m_filenames[fileID] = pathname; m_fileWrapperLock.unlock(); } m_callbackLock.lock(); if (!m_fileOpenCallbacks.isEmpty()) { QString path(pathname); QHashIterator<QString,Callback> it(m_fileOpenCallbacks); while (it.hasNext()) { it.next(); if (path.startsWith(it.key())) it.value().m_callback(it.value().m_object); } } m_callbackLock.unlock(); return fileID; }