예제 #1
1
void ThreadServerPool::requestStop(void)
{
    QMutexLocker locker(&this->_mutex);
    this->_stopRequested = true;

    // Request stop for all threads client
    foreach (ThreadClient* threadClient, this->_threadsClient)
        threadClient->requestStop();

    // Wake all threads client which could be blocked on QWaitCondition
    clientsIsNotEmpty.wakeAll();

    // Wait until all threads client stop
    foreach (ThreadClient* threadClient, this->_threadsClient)
            threadClient->wait();

    // Free client sockets
    conditionMutex.lock();
    clients.clear();
    conditionMutex.unlock();

    // Interrupt server blocking function
    if (this->_socketServer != NULL && this->_socketServer->isValid())
    {
        delete this->_socketServer; // Shutdown and close
        this->_socketServer = NULL;
    }
}
예제 #2
1
 void stop()
 {
     m_bQuitRequest=true;
     m_pDataReady->wakeAll();
     wait();
     m_bQuitRequest=false;
 };
예제 #3
0
GenericSchedulerThread::ThreadStateEnum
GenericSchedulerThreadPrivate::resolveState()
{
    GenericSchedulerThread::ThreadStateEnum ret = GenericSchedulerThread::eThreadStateActive;

    // flag that we have quit the thread
    {
        QMutexLocker k(&mustQuitMutex);
        if (mustQuit) {
            mustQuit = false;
            startingThreadAllowed = lastQuitThreadAllowedRestart;
            ret = GenericSchedulerThread::eThreadStateStopped;
            // Wake up threads waiting in waitForThreadToQuit
            mustQuitCond.wakeAll();
        }
    }

    {
        QMutexLocker k(&abortRequestedMutex);
        if (abortRequested > 0) {
            if (ret == GenericSchedulerThread::eThreadStateActive) {
                ret = GenericSchedulerThread::eThreadStateAborted;
            }
        }
    }


    return ret;
}
예제 #4
0
 static void PostLoad(const QString &cacheKey)
 {
     m_loadingImagesLock.lock();
     m_loadingImages.remove(cacheKey);
     m_loadingImagesCond.wakeAll();
     m_loadingImagesLock.unlock();
 }
예제 #5
0
void QtMediaPlayerJNI::WakeUpThread()
{
    while(mutexload==NULL);
    mutexload->lock();
    waitCondition.wakeAll();
    mutexload->unlock();
    mutexload = NULL;
}
예제 #6
0
파일: EmulApp.cpp 프로젝트: jerlich/rt-fsm
void SndThr::gotSound(unsigned id)
{
    (void)id;
    mut2.lock();
    sndDone = true;
    mut2.unlock();
    //Debug() << "EmulApp manual trigger thread will be woken up for trigger " << trig;
    cond2.wakeAll();
}
예제 #7
0
파일: EmulApp.cpp 프로젝트: jerlich/rt-fsm
void SndThr::triggered(int trig)
{
    (void)trig;
    mut.lock();
    trigDone = true;
    mut.unlock();
    //Debug() << "EmulApp manual trigger thread will be woken up for trigger " << trig;
    cond.wakeAll();
}
예제 #8
0
// Wake from executive wait condition (RT-safe).
void qmidinetJackMidiThread::sync (void)
{
	if (m_mutex.tryLock()) {
		m_cond.wakeAll();
		m_mutex.unlock();
	}
#ifdef CONFIG_DEBUG
	else qDebug("qmidinetJackMidiThread[%p]::sync(): tryLock() failed.", this);
#endif
}
예제 #9
0
/// \brief  Handles messages received from logging clients
/// \param  msg    The message received (can be multi-part)
void LogServerThread::receivedMessage(const QList<QByteArray> &msg)
{
    LogMessage *message = new LogMessage(msg);
    QMutexLocker lock(&logMsgListMutex);

    bool wasEmpty = logMsgList.isEmpty();
    logMsgList.append(message);

    if (wasEmpty)
        logMsgListNotEmpty.wakeAll();
}
예제 #10
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();
 }
예제 #11
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();
 }
예제 #12
0
void AsyncWorker::assignRequest(QOrganizerAbstractRequest* r)
{
    QMutexLocker lock(&m_lock);
    Q_ASSERT_X(!m_req, "Worker", "Something is wrong with locking mechanism!");
    m_req = r;

    //either start the thread if is not running or wake up the sleeping thread
    if (!isRunning())
        start();
    else
        m_wait.wakeAll();
}
예제 #13
0
void AsyncWorker::kill()
{
    {
        QMutexLocker locker(&m_lock);

        //mark the exit flag and wake up the thread if is sleeping
        m_kill = true;
        m_wait.wakeAll();
    }

    //wait the thread to finish
    wait();
}
예제 #14
0
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";


}
예제 #15
0
    void run()
    {
        _qCoreApplication.reset(new QCoreApplication(_dummyArgc, const_cast<char**>(&_dummyArgs[0])));
        OsmAnd::initializeInAppThread();
        {
            QMutexLocker scopedLocker(&_qCoreApplicationThreadMutex);

            wasInitialized = true;

            _qCoreApplicationThreadWaitCondition.wakeAll();
        }
        QCoreApplication::exec();
        OsmAnd::releaseInAppThread();
        _qCoreApplication.reset();
    }
예제 #16
0
파일: main.cpp 프로젝트: TraumLou/qt
void Producer::run()
{
    for (int i = 0; i < DataSize; ++i) {
        mutex.lock();

        if (numUsedBytes == BufferSize) {
            bufferEmpty.wait(&mutex);
        }
        buffer[i % BufferSize] = numUsedBytes;
        ++numUsedBytes;
        bufferFull.wakeAll();

        mutex.unlock();
    }
}
예제 #17
0
void Consumer::run()
{
    for (int i = 0; i < DataSize; ++i) {
        mutex.lock();
        if (numUsedBytes == 0)
            bufferNotEmpty.wait(&mutex);
        mutex.unlock();

        fprintf(stderr, "%c", buffer[i % BufferSize]);

        mutex.lock();
        --numUsedBytes;
        bufferNotFull.wakeAll();
        mutex.unlock();
    }
    fprintf(stderr, "\n");
}
예제 #18
0
void GfxImageLoaderEngine::load(GfxImageLoader *out, const QString &filename, 
                                const QList<QSize> &sizes)
{
    lock.lock();

    bool wasEmpty = ops.isEmpty();
    Op op;
    op.filename = filename;
    op.sizes = sizes;
    op.id = id++;
    op.out = out;
    ops.insert(out, op);

    if(wasEmpty)
        wait.wakeAll();
    lock.unlock();
}
예제 #19
0
    void run()
    {
        qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));

        for (int i = 0; i < DataSize; ++i) {
            mutex.lock();
            if (numUsedBytes == BufferSize)
                bufferNotFull.wait(&mutex);
            mutex.unlock();

            buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4];

            mutex.lock();
            ++numUsedBytes;
            bufferNotEmpty.wakeAll();
            mutex.unlock();
        }
    }
예제 #20
0
void OsmAnd::Concurrent::Dispatcher::invoke(const Delegate method)
{
    assert(method != nullptr);

    QMutex waitMutex;
    QWaitCondition waitCondition;
    invokeAsync([&waitCondition, &waitMutex, method]
    {
        method();

        {
            QMutexLocker scopedLocker(&waitMutex);
            waitCondition.wakeAll();
        }
    });

    {
        QMutexLocker scopedLocker(&waitMutex);
        REPEAT_UNTIL(waitCondition.wait(&waitMutex));
    }
}
예제 #21
0
void SimulationLocker::lockFor(long msecs)
{
    m_lockDuration = msecs<0 ? 0 : msecs;
    adjustLockDuration();

    auto startPause = [this]() {
        auto conn = connect(this, SIGNAL(_startIt()), &m_lockTimer, SLOT(start()));
        emit _startIt(); // make sure timer starts in gui thread
        QObject::disconnect(conn);
    };

    QMutex mutex;
    QWaitCondition condition;
    auto connexion = connect(&m_lockTimer, &QTimer::timeout, [&condition](){condition.wakeAll();});

    mutex.lock();
    startPause(); // to make sure timer starts in this' thread (gui thread)
    condition.wait(&mutex);
    mutex.unlock();

    QObject::disconnect(connexion);
}
예제 #22
0
QImage QtZLWorker::loadCover(const QString &id)
{
    QByteArray pathRaw = QByteArray::fromBase64(id.toLatin1());
    QMutex mutex;
    QWaitCondition cond;
    QImage result;
    bool ready = false;
    
    auto work = [pathRaw, &result, &ready, &mutex, &cond] () {
        ZLFile file(std::string(pathRaw.constData(), pathRaw.size()));
        shared_ptr<FormatPlugin> plugin = PluginCollection::Instance().plugin(file, false);
        
        if (!plugin.isNull()) {
            shared_ptr<const ZLImage> image = plugin->coverImage(file);
            
            if (!image.isNull()) {
                shared_ptr<ZLImageData> data = ZLImageManager::Instance().imageData(*image);
                
                if (!data.isNull())
                    result = static_cast<QtZLImageData &>(*data).toImage();
            }
        }
        
        QMutexLocker locker(&mutex);
        ready = true;
        cond.wakeAll();
    };
    
    selfMethod.invoke(this, Qt::QueuedConnection, Q_ARG(QtZLWork, work));
    
    
    QMutexLocker locker(&mutex);
    while (!ready)
        cond.wait(&mutex);
    
    return result;
}
예제 #23
0
 void run()
 {
     SireError::setThreadString("Promise");
     SireMaths::seed_qrand();
     
     QMutexLocker lkr(&datamutex);
     
     //get a local copy of the node
     Node my_node = node;
     lkr.unlock();
     
     //wait until the job has finished
     my_node.wait();
     
     //the node has finished - grab the result and
     //drop our copy of the node
     WorkPacket my_result = my_node.result();
     
     if (my_result.isNull())
     {
         //where did the result go???
         my_result = ErrorPacket( SireError::program_bug( QObject::tr(
                         "There was no result from the running calculation!!!"),
                             CODELOC ) );
     }
     
     //copy the result to the promise
     lkr.relock();
     result_packet = my_result;
     
     //drop the reference to the node
     node = Node();
     
     //wake anyone waiting for a result
     waiter.wakeAll();
 }
예제 #24
0
bool QgsWfsRequest::sendGET( const QUrl &url, bool synchronous, bool forceRefresh, bool cache )
{
  abort(); // cancel previous
  mIsAborted = false;
  mTimedout = false;
  mGotNonEmptyResponse = false;

  mErrorMessage.clear();
  mErrorCode = QgsWfsRequest::NoError;
  mForceRefresh = forceRefresh;
  mResponse.clear();

  QUrl modifiedUrl( url );

  // Specific code for testing
  if ( modifiedUrl.toString().contains( QLatin1String( "fake_qgis_http_endpoint" ) ) )
  {
    // Just for testing with local files instead of http:// resources
    QString modifiedUrlString = modifiedUrl.toString();
    // Qt5 does URL encoding from some reason (of the FILTER parameter for example)
    modifiedUrlString = QUrl::fromPercentEncoding( modifiedUrlString.toUtf8() );
    QgsDebugMsgLevel( QStringLiteral( "Get %1" ).arg( modifiedUrlString ), 4 );
    modifiedUrlString = modifiedUrlString.mid( QStringLiteral( "http://" ).size() );
    QString args = modifiedUrlString.mid( modifiedUrlString.indexOf( '?' ) );
    if ( modifiedUrlString.size() > 256 )
    {
      args = QCryptographicHash::hash( args.toUtf8(), QCryptographicHash::Md5 ).toHex();
    }
    else
    {
      args.replace( QLatin1String( "?" ), QLatin1String( "_" ) );
      args.replace( QLatin1String( "&" ), QLatin1String( "_" ) );
      args.replace( QLatin1String( "<" ), QLatin1String( "_" ) );
      args.replace( QLatin1String( ">" ), QLatin1String( "_" ) );
      args.replace( QLatin1String( "'" ), QLatin1String( "_" ) );
      args.replace( QLatin1String( "\"" ), QLatin1String( "_" ) );
      args.replace( QLatin1String( " " ), QLatin1String( "_" ) );
      args.replace( QLatin1String( ":" ), QLatin1String( "_" ) );
      args.replace( QLatin1String( "/" ), QLatin1String( "_" ) );
      args.replace( QLatin1String( "\n" ), QLatin1String( "_" ) );
    }
#ifdef Q_OS_WIN
    // Passing "urls" like "http://c:/path" to QUrl 'eats' the : after c,
    // so we must restore it
    if ( modifiedUrlString[1] == '/' )
    {
      modifiedUrlString = modifiedUrlString[0] + ":/" + modifiedUrlString.mid( 2 );
    }
#endif
    modifiedUrlString = modifiedUrlString.mid( 0, modifiedUrlString.indexOf( '?' ) ) + args;
    QgsDebugMsgLevel( QStringLiteral( "Get %1 (after laundering)" ).arg( modifiedUrlString ), 4 );
    modifiedUrl = QUrl::fromLocalFile( modifiedUrlString );
  }

  QgsDebugMsgLevel( QStringLiteral( "Calling: %1" ).arg( modifiedUrl.toDisplayString( ) ), 4 );

  QNetworkRequest request( modifiedUrl );
  if ( !mUri.auth().setAuthorization( request ) )
  {
    mErrorCode = QgsWfsRequest::NetworkError;
    mErrorMessage = errorMessageFailedAuth();
    QgsMessageLog::logMessage( mErrorMessage, tr( "WFS" ) );
    return false;
  }

  if ( cache )
  {
    request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, forceRefresh ? QNetworkRequest::AlwaysNetwork : QNetworkRequest::PreferCache );
    request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
  }

  QWaitCondition waitCondition;
  QMutex waitConditionMutex;
  bool threadFinished = false;
  bool success = false;

  std::function<void()> downloaderFunction = [ this, request, synchronous, &waitConditionMutex, &waitCondition, &threadFinished, &success ]()
  {
    if ( QThread::currentThread() != QgsApplication::instance()->thread() )
      QgsNetworkAccessManager::instance( Qt::DirectConnection );

    success = true;
    mReply = QgsNetworkAccessManager::instance()->get( request );

    mReply->setReadBufferSize( READ_BUFFER_SIZE_HINT );
    if ( !mUri.auth().setAuthorizationReply( mReply ) )
    {
      mErrorCode = QgsWfsRequest::NetworkError;
      mErrorMessage = errorMessageFailedAuth();
      QgsMessageLog::logMessage( mErrorMessage, tr( "WFS" ) );
      waitCondition.wakeAll();
      success = false;
    }
    else
    {
      // We are able to use direct connection here, because we
      // * either run on the thread mReply lives in, so DirectConnection is standard and safe anyway
      // * or the owner thread of mReply is currently not doing anything because it's blocked in future.waitForFinished() (if it is the main thread)
      connect( mReply, &QNetworkReply::finished, this, &QgsWfsRequest::replyFinished, Qt::DirectConnection );
      connect( mReply, &QNetworkReply::downloadProgress, this, &QgsWfsRequest::replyProgress, Qt::DirectConnection );

      if ( synchronous )
      {
        auto resumeMainThread = [&waitConditionMutex, &waitCondition]()
        {
          waitConditionMutex.lock();
          waitCondition.wakeAll();
          waitConditionMutex.unlock();

          waitConditionMutex.lock();
          waitCondition.wait( &waitConditionMutex );
          waitConditionMutex.unlock();
        };

        connect( QgsNetworkAccessManager::instance(), &QgsNetworkAccessManager::authenticationRequired, this, resumeMainThread, Qt::DirectConnection );
        connect( QgsNetworkAccessManager::instance(), &QgsNetworkAccessManager::proxyAuthenticationRequired, this, resumeMainThread, Qt::DirectConnection );

#ifndef QT_NO_SSL
        connect( QgsNetworkAccessManager::instance(), &QgsNetworkAccessManager::sslErrors, this, resumeMainThread, Qt::DirectConnection );
#endif
        QEventLoop loop;
        connect( this, &QgsWfsRequest::downloadFinished, &loop, &QEventLoop::quit, Qt::DirectConnection );
        loop.exec();
      }
    }
    waitConditionMutex.lock();
    threadFinished = true;
    waitCondition.wakeAll();
    waitConditionMutex.unlock();
  };

  if ( synchronous && QThread::currentThread() == QApplication::instance()->thread() )
  {
    std::unique_ptr<DownloaderThread> downloaderThread = qgis::make_unique<DownloaderThread>( downloaderFunction );
    downloaderThread->start();

    while ( true )
    {
      waitConditionMutex.lock();
      if ( threadFinished )
      {
        waitConditionMutex.unlock();
        break;
      }
      waitCondition.wait( &waitConditionMutex );

      // If the downloader thread wakes us (the main thread) up and is not yet finished
      // he needs the authentication to run.
      // The processEvents() call gives the auth manager the chance to show a dialog and
      // once done with that, we can wake the downloaderThread again and continue the download.
      if ( !threadFinished )
      {
        waitConditionMutex.unlock();

        QgsApplication::instance()->processEvents();
        waitConditionMutex.lock();
        waitCondition.wakeAll();
        waitConditionMutex.unlock();
      }
      else
      {
        waitConditionMutex.unlock();
      }
    }
    // wait for thread to gracefully exit
    downloaderThread->wait();
  }
  else
  {
    downloaderFunction();
  }
  return success && mErrorMessage.isEmpty();
}
예제 #25
0
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);
    }
}
예제 #26
0
void SendDataThread::sendData(const QByteArray &data)
{
	QMutexLocker locker(&m_DataMutex);
	m_DataList.push_back(data);
	m_DataCondition.wakeAll();
}
예제 #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
                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));
            }
        }
    }
}
예제 #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 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 ModelPropertyAnimation::trigger(QAbstractAnimation *animation, bool synchrone, DeletionContext deletionContext)
{
    /* The connexion below won't delete indefinitely looping animation.
     * To avoid memory leaks, the deletionContext paramater is introduced.
     */
    connect(animation, &QAbstractAnimation::finished, [=](){animation->deleteLater();});

    /* Considering what's stated in Qt's doc about Qt::AutoConnection behaviour
     * (see QObject::connect), we need to make sure
     *     ESPECIALLY WHEN this function is called from a thread other than the gui-thread:
     *         from an algorithm thread for instance,
     * that the animation passed as parameter leaves in the gui-thread,
     * so that it can perform flawlessly.
     *
     * Indeed, IN THAT CASE, performing a direct call to QAbstractAnimation::start causes the animation
     * not to perform in the way it should. So we first move it to the gui-thread and then
     * emit a signal which finally triggers its execution.
     *
     * This isn't probably the best way to address this issue, but it works.
     */
    // connect(this, &ModelPropertyAnimation::_startIt, animation, &QAbstractAnimation::start);
    // the previous syntax doesn't work due to argument count mismatching.
    connect(this, SIGNAL(_startIt()), animation, SLOT(start()));
    animation->moveToThread(QApplication::instance()->thread());
    auto startAnimation = [=]() { // define a function that will start the animation
        emit _startIt();
        // disconnect the signal, to make sure any further emission is ignored.
        disconnect(this, SIGNAL(_startIt()), animation, SLOT(start()));
    };

    QThread *t = nullptr;
    switch(deletionContext) {
    case None:                                               break;
    case ThisThread: t = thread();                           break;
    case GuiThread:  t = QApplication::instance()->thread(); break;
    }
    if(t) {
        connect(t, &QThread::finished, animation, &QAbstractAnimation::deleteLater);
    }

    if(!synchrone) {
        startAnimation();
    }
    else {
        QMutex mutex;
        QWaitCondition condition;
        auto connexion = connect(animation, &QAbstractAnimation::finished, [&condition](){condition.wakeAll();});

        mutex.lock();
        startAnimation();
        condition.wait(&mutex);
        mutex.unlock();

        disconnect(connexion);
    }
}