bool ScriptJob::waitFor( QObject *sender, const char *signal, WaitForType type ) { // The called function returned, but asynchronous network requests may have been started. // Wait for all network requests to finish, because slots in the script may get called const int finishWaitTime = 100; int finishWaitCounter = 0; m_mutex->lockInline(); bool success = m_success; bool quit = m_quit; if ( !success || quit ) { m_mutex->unlockInline(); return true; } QScriptEngine *engine = m_engine; ScriptObjects objects = m_objects; m_mutex->unlockInline(); while ( finishWaitCounter < 50 && sender ) { if ( (type == WaitForNetwork && !objects.network->hasRunningRequests()) || (type == WaitForScriptFinish && !engine->isEvaluating()) || (type == WaitForNothing && finishWaitCounter > 0) ) { break; } QEventLoop loop; connect( sender, signal, &loop, SLOT(quit()) ); QTimer::singleShot( finishWaitTime, &loop, SLOT(quit()) ); // Store a pointer to the event loop, to be able to quit it from the destructor m_mutex->lockInline(); m_eventLoop = &loop; m_mutex->unlockInline(); // Engine continues execution here / waits for a signal loop.exec(); QMutexLocker locker( m_mutex ); if ( !m_eventLoop || m_quit ) { // Job was aborted m_engine = 0; m_objects.clear(); engine->deleteLater(); return false; } m_eventLoop = 0; ++finishWaitCounter; } if ( finishWaitCounter >= 50 && type == WaitForScriptFinish ) { // Script not finished engine->abortEvaluation(); } return finishWaitCounter < 50; }
ControllerEngine::~ControllerEngine() { // Clean up for (int i=0; i < kDecks; i++) { delete m_pitchFilter[i]; m_pitchFilter[i] = NULL; } // Delete the script engine, first clearing the pointer so that // other threads will not get the dead pointer after we delete it. if (m_pEngine != NULL) { QScriptEngine *engine = m_pEngine; m_pEngine = NULL; engine->deleteLater(); } }