void waitForStart() { m_started.lock(); m_started.unlock(); }
void QVideoDecoder::decode() { if(m_video->m_status == QVideo::NotRunning) return; emit ready(false); AVPacket pkt1, *packet = &pkt1; double pts; int frame_finished = 0; while(!frame_finished && !m_killed) { if(av_read_frame(m_av_format_context, packet) >= 0) { // Is this a packet from the video stream? if(packet->stream_index == m_video_stream) { global_video_pkt_pts = packet->pts; // mutex.lock(); avcodec_decode_video(m_video_codec_context, m_av_frame, &frame_finished, packet->data, packet->size); // mutex.unlock(); if(packet->dts == AV_NOPTS_VALUE && m_av_frame->opaque && *(uint64_t*)m_av_frame->opaque != AV_NOPTS_VALUE) { pts = *(uint64_t *)m_av_frame->opaque; } else if(packet->dts != AV_NOPTS_VALUE) { pts = packet->dts; } else { pts = 0; } pts *= av_q2d(m_timebase); // Did we get a video frame? if(frame_finished) { // size_t num_native_bytes = m_av_frame->linesize[0] * m_video_codec_context->height; // size_t num_rgb_bytes = m_av_rgb_frame->linesize[0] * m_video_codec_context->height; // Convert the image from its native format to RGB, then copy the image data to a QImage if(m_sws_context == NULL) { mutex.lock(); m_sws_context = sws_getContext( m_video_codec_context->width, m_video_codec_context->height, m_video_codec_context->pix_fmt, m_video_codec_context->width, m_video_codec_context->height, //PIX_FMT_RGB32,SWS_BICUBIC, RAW_PIX_FMT, SWS_FAST_BILINEAR, NULL, NULL, NULL); //SWS_PRINT_INFO mutex.unlock(); //printf("decode(): created m_sws_context\n"); } //printf("decode(): got frame\n"); // mutex.lock(); sws_scale(m_sws_context, m_av_frame->data, m_av_frame->linesize, 0, m_video_codec_context->height, m_av_rgb_frame->data, m_av_rgb_frame->linesize); // mutex.unlock(); // size_t num_bytes = m_av_rgb_frame->linesize[0] * m_video_codec_context->height; // if(m_frame) // delete m_frame; m_frame = QImage(m_av_rgb_frame->data[0], m_video_codec_context->width, m_video_codec_context->height, QImage::Format_RGB16); av_free_packet(packet); // This block from the synchronize_video(VideoState *is, AVFrame *src_frame, double pts) : double // function given at: http://www.dranger.com/ffmpeg/tutorial05.html { // update the frame pts double frame_delay; if(pts != 0) { /* if we have pts, set video clock to it */ m_video_clock = pts; } else { /* if we aren't given a pts, set it to the clock */ pts = m_video_clock; } /* update the video clock */ frame_delay = av_q2d(m_timebase); /* if we are repeating a frame, adjust clock accordingly */ frame_delay += m_av_frame->repeat_pict * (frame_delay * 0.5); m_video_clock += frame_delay; //qDebug() << "Frame Dealy: "<<frame_delay; } QFFMpegVideoFrame video_frame; video_frame.frame = &m_frame; video_frame.pts = pts; video_frame.previous_pts = m_previous_pts; m_current_frame = video_frame; emit newFrame(video_frame); m_previous_pts = pts; //QTimer::singleShot(5, this, SLOT(decode())); } } else if(packet->stream_index == m_audio_stream) { // mutex.lock(); //decode audio packet, store in queue av_free_packet(packet); // mutex.unlock(); } else { // mutex.lock(); av_free_packet(packet); // mutex.unlock(); } } else { emit reachedEnd(); } } }
void MythSystemLegacyManager::run(void) { RunProlog(); LOG(VB_GENERAL, LOG_INFO, "Starting process manager"); // run_system is set to false during shutdown, and we need this thread to // exit during shutdown. while( run_system ) { // check for any running processes m_mapLock.lock(); if( m_childCount == 0 ) { m_mapLock.unlock(); usleep( 100000 ); continue; } DWORD result = WaitForMultipleObjects( m_childCount, m_children, FALSE, 100 ); if ( result == WAIT_TIMEOUT || result == WAIT_FAILED ) { m_mapLock.unlock(); continue; } int index = result - WAIT_OBJECT_0; if ( index < 0 || index > m_childCount - 1 ) { m_mapLock.unlock(); continue; } HANDLE child = m_children[index]; // pop exited process off managed list, add to cleanup list MythSystemLegacyWindows *ms = m_pMap.take(child); ChildListRebuild(); m_mapLock.unlock(); // Occasionally, the caller has deleted the structure from under // our feet. If so, just log and move on. if (!ms || !ms->m_parent) { LOG(VB_SYSTEM, LOG_ERR, QString("Structure for child handle %1 already deleted!") .arg((long long)child)); if (ms) { listLock.lock(); msList.append(ms); listLock.unlock(); } continue; } listLock.lock(); msList.append(ms); DWORD status; GetExitCodeProcess( child, &status ); ms->SetStatus(status); LOG(VB_SYSTEM, LOG_INFO, QString("Managed child (Handle: %1) has exited! " "command=%2, status=%3, result=%4") .arg((long long)child) .arg(ms->GetLogCmd()) .arg(status) .arg(ms->GetStatus())); // loop through running processes for any that require action MSMap_t::iterator i; time_t now = time(nullptr); m_mapLock.lock(); m_jumpLock.lock(); for (i = m_pMap.begin(); i != m_pMap.end(); ++i) { child = i.key(); ms = i.value(); // handle processes beyond marked timeout if( ms->m_timeout > 0 && ms->m_timeout < now ) { // issuing KILL signal after TERM failed in a timely manner if( ms->GetStatus() == GENERIC_EXIT_TIMEOUT ) { LOG(VB_SYSTEM, LOG_INFO, QString("Managed child (Handle: %1) timed out, " "issuing KILL signal").arg((long long)child)); // Prevent constant attempts to kill an obstinate child ms->m_timeout = 0; ms->Signal(SIGKILL); } // issuing TERM signal else { LOG(VB_SYSTEM, LOG_INFO, QString("Managed child (Handle: %1) timed out" ", issuing TERM signal").arg((long long)child)); ms->SetStatus( GENERIC_EXIT_TIMEOUT ); ms->m_timeout = now + 1; ms->Term(); } } if ( m_jumpAbort && ms->GetSetting("AbortOnJump") ) ms->Term(); } m_jumpAbort = false; m_jumpLock.unlock(); m_mapLock.unlock(); // hold off unlocking until all the way down here to // give the buffer handling a chance to run before // being closed down by signal thread listLock.unlock(); } // kick to allow them to close themselves cleanly readThread->wake(); writeThread->wake(); RunEpilog(); }
//from http://jpassing.com/2008/03/12/walking-the-stack-of-the-current-thread/ // http://www.codeproject.com/Articles/11132/Walking-the-callstack //alternative: __builtin_return_address, but it is said to not work so well QString getBacktrace(){ if (!backtraceMutex.tryLock()) return "locked"; //init crap HANDLE process = GetCurrentProcess(); HANDLE thread = GetCurrentThread(); QStringList result(initDebugHelp()); CONTEXT context; ZeroMemory( &context, sizeof( CONTEXT ) ); STACKFRAME64 stackFrame; #if (defined(x86_64) || defined(__x86_64__)) RtlCaptureContext( &context ); #else // Those three registers are enough. geteip: context.Eip = (DWORD)&&geteip; __asm__( "mov %%ebp, %0\n" "mov %%esp, %1" : "=r"(context.Ebp), "=r"(context.Esp)); #endif ZeroMemory( &stackFrame, sizeof( stackFrame ) ); #ifdef CPU_IS_64 DWORD machineType = IMAGE_FILE_MACHINE_AMD64; stackFrame.AddrPC.Offset = context.Rip; stackFrame.AddrPC.Mode = AddrModeFlat; stackFrame.AddrFrame.Offset = context.Rbp;//changed from rsp. correctly? stackFrame.AddrFrame.Mode = AddrModeFlat; stackFrame.AddrStack.Offset = context.Rsp; stackFrame.AddrStack.Mode = AddrModeFlat; #else DWORD machineType = IMAGE_FILE_MACHINE_I386; stackFrame.AddrPC.Offset = context.Eip; stackFrame.AddrPC.Mode = AddrModeFlat; stackFrame.AddrFrame.Offset = context.Ebp; stackFrame.AddrFrame.Mode = AddrModeFlat; stackFrame.AddrStack.Offset = context.Esp; stackFrame.AddrStack.Mode = AddrModeFlat; /* #elif _M_IA64 MachineType = IMAGE_FILE_MACHINE_IA64; StackFrame.AddrPC.Offset = Context.StIIP; StackFrame.AddrPC.Mode = AddrModeFlat; StackFrame.AddrFrame.Offset = Context.IntSp; StackFrame.AddrFrame.Mode = AddrModeFlat; StackFrame.AddrBStore.Offset= Context.RsBSP; StackFrame.AddrBStore.Mode = AddrModeFlat; StackFrame.AddrStack.Offset = Context.IntSp; StackFrame.AddrStack.Mode = AddrModeFlat; #else #error "Unsupported platform"*/ #endif static HMODULE dbghelp = LoadLibraryA("dbghelp.dll"); if (!dbghelp) return "failed to load dbghelp.dll"; LOAD_FUNCTIONREQ(StackWalk64, "StackWalk64"); LOAD_FUNCTIONREQ(SymGetModuleBase64, "SymGetModuleBase64"); LOAD_FUNCTIONREQ(SymFunctionTableAccess64, "SymFunctionTableAccess64"); //get stackframes QList<DWORD64> stackFrames; while ((*StackWalk64)(machineType, process, thread, &stackFrame, &context, 0, SymFunctionTableAccess64, SymGetModuleBase64, 0)) stackFrames << stackFrame.AddrPC.Offset; result << lookUpAddresses(stackFrames); backtraceMutex.unlock(); return result.join("\r\n"); }
namespace KSaneIface { static FindSaneDevicesThread *s_instancesane = 0; static QMutex s_mutexsane; FindSaneDevicesThread *FindSaneDevicesThread::getInstance() { s_mutexsane.lock(); if (s_instancesane == 0) { s_instancesane = new FindSaneDevicesThread(); } s_mutexsane.unlock(); return s_instancesane; } FindSaneDevicesThread::FindSaneDevicesThread() : QThread(0) { } FindSaneDevicesThread::~FindSaneDevicesThread() { s_mutexsane.lock(); wait(); s_mutexsane.unlock(); } void FindSaneDevicesThread::run() { SANE_Device const **devList; //SANE_Int version; SANE_Status status; // This is unfortunately not very reliable as many back-ends do not refresh // the device list after the sane_init() call... status = sane_get_devices(&devList, SANE_FALSE); m_deviceList.clear(); if (status == SANE_STATUS_GOOD) { int i = 0; KSaneWidget::DeviceInfo tmp; while(devList[i] != 0) { tmp.name = devList[i]->name; tmp.vendor = devList[i]->vendor; tmp.model = devList[i]->model; tmp.type = devList[i]->type; m_deviceList << tmp; i++; } } } const QList<KSaneWidget::DeviceInfo> FindSaneDevicesThread::devicesList() const { return m_deviceList; } }
~autolock () { mutex.unlock(); }
void malletsInstrument::playNote( NotePlayHandle * _n, sampleFrame * _working_buffer ) { if( m_filesMissing ) { return; } int p = m_presetsModel.value(); const float freq = _n->frequency(); if ( _n->totalFramesPlayed() == 0 || _n->m_pluginData == NULL ) { const float vel = _n->getVolume() / 100.0f; // critical section as STK is not thread-safe static QMutex m; m.lock(); if( p < 9 ) { _n->m_pluginData = new malletsSynth( freq, vel, m_vibratoGainModel.value(), m_hardnessModel.value(), m_positionModel.value(), m_stickModel.value(), m_vibratoFreqModel.value(), p, (uint8_t) m_spreadModel.value(), engine::mixer()->processingSampleRate() ); } else if( p == 9 ) { _n->m_pluginData = new malletsSynth( freq, vel, p, m_lfoDepthModel.value(), m_modulatorModel.value(), m_crossfadeModel.value(), m_lfoSpeedModel.value(), m_adsrModel.value(), (uint8_t) m_spreadModel.value(), engine::mixer()->processingSampleRate() ); } else { _n->m_pluginData = new malletsSynth( freq, vel, m_pressureModel.value(), m_motionModel.value(), m_vibratoModel.value(), p - 10, m_strikeModel.value() * 128.0, m_velocityModel.value(), (uint8_t) m_spreadModel.value(), engine::mixer()->processingSampleRate() ); } m.unlock(); } const fpp_t frames = _n->framesLeftForCurrentPeriod(); const f_cnt_t offset = _n->noteOffset(); malletsSynth * ps = static_cast<malletsSynth *>( _n->m_pluginData ); ps->setFrequency( freq ); sample_t add_scale = 0.0f; if( p == 10 ) { add_scale = static_cast<sample_t>( m_strikeModel.value() ) * freq * 2.5f; } for( fpp_t frame = offset; frame < frames + offset; ++frame ) { _working_buffer[frame][0] = ps->nextSampleLeft() * ( m_scalers[m_presetsModel.value()] + add_scale ); _working_buffer[frame][1] = ps->nextSampleRight() * ( m_scalers[m_presetsModel.value()] + add_scale ); } instrumentTrack()->processAudioBuffer( _working_buffer, frames + offset, _n ); }
virtual void paintGL() { mutex.lock(); frame(); mutex.unlock(); }
void tst_QMutex::lock_unlock_locked_tryLock() { // normal mutex QMutex mutex; mutex_Thread thread(mutex); QMutex rmutex(QMutex::Recursive); rmutex_Thread rthread(rmutex); for (int i = 0; i < iterations; ++i) { // normal mutex QVERIFY(mutex.tryLock()); mutex.unlock(); thread.mutex.lock(); thread.start(); for (int j = 0; j < iterations; ++j) { QVERIFY(thread.cond.wait(&thread.mutex, 10000)); QVERIFY(!mutex.tryLock()); thread.cond.wakeOne(); } thread.mutex.unlock(); QVERIFY(thread.wait(10000)); QVERIFY(mutex.tryLock()); mutex.unlock(); // recursive mutex QVERIFY(rmutex.tryLock()); QVERIFY(rmutex.tryLock()); QVERIFY(rmutex.tryLock()); QVERIFY(rmutex.tryLock()); rmutex.unlock(); rmutex.unlock(); rmutex.unlock(); rmutex.unlock(); rthread.mutex.lock(); rthread.start(); for (int k = 0; k < iterations; ++k) { QVERIFY(rthread.cond.wait(&rthread.mutex, 10000)); QVERIFY(!rmutex.tryLock()); rthread.cond.wakeOne(); } rthread.mutex.unlock(); QVERIFY(rthread.wait(10000)); QVERIFY(rmutex.tryLock()); QVERIFY(rmutex.tryLock()); QVERIFY(rmutex.tryLock()); QVERIFY(rmutex.tryLock()); rmutex.unlock(); rmutex.unlock(); rmutex.unlock(); rmutex.unlock(); } }
virtual void BeginPaint() { paintLock.lock(); Clear(); }
virtual void EndPaint() { paintLock.unlock(); }
void MutexKnobData::DataUnlock(knobData *kData) { QMutex *datamutex; datamutex = (QMutex*) kData->mutex; datamutex->unlock(); }
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 ); QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsWfsRequest" ) ); 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]() { // when this method is called we have "produced" a single authentication request -- so the buffer is now full // and it's time for the "consumer" (main thread) to do its part waitConditionMutex.lock(); waitCondition.wakeAll(); waitConditionMutex.unlock(); // note that we don't need to handle waking this thread back up - that's done automatically by QgsNetworkAccessManager }; connect( QgsNetworkAccessManager::instance(), &QgsNetworkAccessManager::authRequestOccurred, this, resumeMainThread, Qt::DirectConnection ); connect( QgsNetworkAccessManager::instance(), &QgsNetworkAccessManager::proxyAuthenticationRequired, this, resumeMainThread, Qt::DirectConnection ); #ifndef QT_NO_SSL connect( QgsNetworkAccessManager::instance(), &QgsNetworkAccessManager::sslErrorsOccurred, 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 // then it has "produced" an authentication request which we need to now "consume". // 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(); // we don't need to wake up the worker thread - it will automatically be woken when // the auth request has been dealt with by QgsNetworkAccessManager } else { waitConditionMutex.unlock(); } } // wait for thread to gracefully exit downloaderThread->wait(); } else { downloaderFunction(); } return success && mErrorMessage.isEmpty(); }
/** * @brief AgentCluster::sleep Pauses the current thread for a designated amount of time. * @param milliseconds Milliseconds to pause for. */ void AgentCluster::sleep(int milliseconds) { QMutex mut; mut.lock(); mut.tryLock(milliseconds); mut.unlock(); }
void concurPrint(int cID, int bID) { static QMutex l; l.lock(); cout << "Customer " << cID << " is being serviced by barber " << bID << endl; l.unlock(); }
void run() { tryLockResult = mut.tryLock(timeout); mut.unlock(); }
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 < 51200) && (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; }
void tst_QMutex::tryLock() { // test non-recursive mutex { class Thread : public QThread { public: void run() { testsTurn.release(); // TEST 1: thread can't acquire lock threadsTurn.acquire(); QVERIFY(!normalMutex.tryLock()); testsTurn.release(); // TEST 2: thread can acquire lock threadsTurn.acquire(); QVERIFY(normalMutex.tryLock()); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(!normalMutex.tryLock()); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); testsTurn.release(); // TEST 3: thread can't acquire lock, timeout = waitTime threadsTurn.acquire(); QTime timer; timer.start(); QVERIFY(!normalMutex.tryLock(waitTime)); QVERIFY(timer.elapsed() >= waitTime); testsTurn.release(); // TEST 4: thread can acquire lock, timeout = waitTime threadsTurn.acquire(); timer.start(); QVERIFY(normalMutex.tryLock(waitTime)); QVERIFY(timer.elapsed() <= waitTime); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); timer.start(); // it's non-recursive, so the following lock needs to fail QVERIFY(!normalMutex.tryLock(waitTime)); QVERIFY(timer.elapsed() >= waitTime); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); testsTurn.release(); // TEST 5: thread can't acquire lock, timeout = 0 threadsTurn.acquire(); QVERIFY(!normalMutex.tryLock(0)); testsTurn.release(); // TEST 6: thread can acquire lock, timeout = 0 threadsTurn.acquire(); timer.start(); QVERIFY(normalMutex.tryLock(0)); QVERIFY(timer.elapsed() < waitTime); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(!normalMutex.tryLock(0)); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); testsTurn.release(); // TEST 7 overflow: thread can acquire lock, timeout = 3000 (QTBUG-24795) threadsTurn.acquire(); timer.start(); QVERIFY(normalMutex.tryLock(3000)); QVERIFY(timer.elapsed() < 3000); normalMutex.unlock(); testsTurn.release(); threadsTurn.acquire(); } }; Thread thread; thread.start(); // TEST 1: thread can't acquire lock testsTurn.acquire(); normalMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); threadsTurn.release(); // TEST 2: thread can acquire lock testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); threadsTurn.release(); // TEST 3: thread can't acquire lock, timeout = waitTime testsTurn.acquire(); normalMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); threadsTurn.release(); // TEST 4: thread can acquire lock, timeout = waitTime testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); threadsTurn.release(); // TEST 5: thread can't acquire lock, timeout = 0 testsTurn.acquire(); normalMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); threadsTurn.release(); // TEST 6: thread can acquire lock, timeout = 0 testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); threadsTurn.release(); // TEST 7: thread can acquire lock, timeout = 3000 (QTBUG-24795) testsTurn.acquire(); normalMutex.lock(); threadsTurn.release(); QThread::msleep(100); normalMutex.unlock(); // wait for thread to finish testsTurn.acquire(); threadsTurn.release(); thread.wait(); } // test recursive mutex { class Thread : public QThread { public: void run() { testsTurn.release(); threadsTurn.acquire(); QVERIFY(!recursiveMutex.tryLock()); testsTurn.release(); threadsTurn.acquire(); QVERIFY(recursiveMutex.tryLock()); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(recursiveMutex.tryLock()); QVERIFY(lockCount.testAndSetRelaxed(1, 2)); QVERIFY(lockCount.testAndSetRelaxed(2, 1)); recursiveMutex.unlock(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); recursiveMutex.unlock(); testsTurn.release(); threadsTurn.acquire(); QTime timer; timer.start(); QVERIFY(!recursiveMutex.tryLock(waitTime)); QVERIFY(timer.elapsed() >= waitTime); QVERIFY(!recursiveMutex.tryLock(0)); testsTurn.release(); threadsTurn.acquire(); timer.start(); QVERIFY(recursiveMutex.tryLock(waitTime)); QVERIFY(timer.elapsed() <= waitTime); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(recursiveMutex.tryLock(waitTime)); QVERIFY(lockCount.testAndSetRelaxed(1, 2)); QVERIFY(lockCount.testAndSetRelaxed(2, 1)); recursiveMutex.unlock(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); recursiveMutex.unlock(); testsTurn.release(); threadsTurn.acquire(); QVERIFY(!recursiveMutex.tryLock(0)); QVERIFY(!recursiveMutex.tryLock(0)); testsTurn.release(); threadsTurn.acquire(); timer.start(); QVERIFY(recursiveMutex.tryLock(0)); QVERIFY(timer.elapsed() < waitTime); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(recursiveMutex.tryLock(0)); QVERIFY(lockCount.testAndSetRelaxed(1, 2)); QVERIFY(lockCount.testAndSetRelaxed(2, 1)); recursiveMutex.unlock(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); recursiveMutex.unlock(); testsTurn.release(); threadsTurn.acquire(); } }; Thread thread; thread.start(); // thread can't acquire lock testsTurn.acquire(); recursiveMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); recursiveMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(1, 2)); threadsTurn.release(); // thread can acquire lock testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(2, 1)); recursiveMutex.unlock(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); recursiveMutex.unlock(); threadsTurn.release(); // thread can't acquire lock, timeout = waitTime testsTurn.acquire(); recursiveMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); recursiveMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(1, 2)); threadsTurn.release(); // thread can acquire lock, timeout = waitTime testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(2, 1)); recursiveMutex.unlock(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); recursiveMutex.unlock(); threadsTurn.release(); // thread can't acquire lock, timeout = 0 testsTurn.acquire(); recursiveMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); recursiveMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(1, 2)); threadsTurn.release(); // thread can acquire lock, timeout = 0 testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(2, 1)); recursiveMutex.unlock(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); recursiveMutex.unlock(); threadsTurn.release(); // stop thread testsTurn.acquire(); threadsTurn.release(); thread.wait(); } }
autolock() { mutex.lock(); }
void run() { testsTurn.release(); // TEST 1: thread can't acquire lock threadsTurn.acquire(); QVERIFY(!normalMutex.tryLock()); testsTurn.release(); // TEST 2: thread can acquire lock threadsTurn.acquire(); QVERIFY(normalMutex.tryLock()); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(!normalMutex.tryLock()); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); testsTurn.release(); // TEST 3: thread can't acquire lock, timeout = waitTime threadsTurn.acquire(); QTime timer; timer.start(); QVERIFY(!normalMutex.tryLock(waitTime)); QVERIFY(timer.elapsed() >= waitTime); testsTurn.release(); // TEST 4: thread can acquire lock, timeout = waitTime threadsTurn.acquire(); timer.start(); QVERIFY(normalMutex.tryLock(waitTime)); QVERIFY(timer.elapsed() <= waitTime); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); timer.start(); // it's non-recursive, so the following lock needs to fail QVERIFY(!normalMutex.tryLock(waitTime)); QVERIFY(timer.elapsed() >= waitTime); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); testsTurn.release(); // TEST 5: thread can't acquire lock, timeout = 0 threadsTurn.acquire(); QVERIFY(!normalMutex.tryLock(0)); testsTurn.release(); // TEST 6: thread can acquire lock, timeout = 0 threadsTurn.acquire(); timer.start(); QVERIFY(normalMutex.tryLock(0)); QVERIFY(timer.elapsed() < waitTime); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); QVERIFY(!normalMutex.tryLock(0)); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); testsTurn.release(); // TEST 7 overflow: thread can acquire lock, timeout = 3000 (QTBUG-24795) threadsTurn.acquire(); timer.start(); QVERIFY(normalMutex.tryLock(3000)); QVERIFY(timer.elapsed() < 3000); normalMutex.unlock(); testsTurn.release(); threadsTurn.acquire(); }
namespace Type { bool equals( const QVariant & a, const QVariant & b ) { return ( a == b ) || Data::equals( a.userType(), a.constData(), b.userType(), b.constData() ); } bool lessThan( const QVariant & a, const QVariant & b ) { return Data::lessThan( a.userType(), a.constData(), b.userType(), b.constData() ); } bool convert( const QVariant & from, QVariant & to ) { const QVariant::Type toType = (QVariant::Type) to.userType(); if( from.canConvert( toType ) ) { to.setValue( from ); return to.convert( toType ); } return Data::convert( from.userType(), from.constData(), toType, const_cast<void*>(to.constData()) ); } bool canConvert( const QVariant & from, int toType ) { return from.canConvert( (QVariant::Type) toType ) || Data::canConvert( from.userType(), toType ); } static QMutex lh_type_data_mutex_; static const Data * lh_first_info_ = 0; static int lh_lock_and_filter( int typeId ) { lh_type_data_mutex_.lock(); if( typeId < QMetaType::User ) { Q_ASSERT( !"LH::Type::Data: type ID < QMetaType::User" ); return 0; } const Data * mt = lh_first_info_; while( mt ) { if( typeId == mt->typeId()) { Q_ASSERT( !"LH::Type::Data: type ID already registered" ); return 0; } mt = mt->next(); } return typeId; } bool Data::equals( int typeId1, const void * p1, int typeId2, const void * p2 ) { const Data * mt = lh_first_info_; while( mt ) { if( typeId1 == mt->typeId_ && mt->equals( p1, typeId2, p2 ) ) return true; if( typeId2 == mt->typeId_ && mt->equals( p2, typeId1, p1 ) ) return true; mt = mt->next_; } return false; } bool Data::lessThan( int typeId1, const void * p1, int typeId2, const void * p2 ) { const Data * mt = lh_first_info_; while( mt ) { if( typeId1 == mt->typeId_ && mt->lessThan( p1, typeId2, p2 ) ) return true; if( typeId2 == mt->typeId_ && mt->lessThan( p2, typeId1, p1 ) ) return false; mt = mt->next_; } return false; } bool Data::convert( int fromTypeId, const void * p, int toTypeId, void * v ) { const Data * mt = lh_first_info_; bool found = false; while( mt ) { if( fromTypeId == mt->typeId() ) { found = true; if( mt->canConvertTo( toTypeId ) ) { return mt->convertTo( p, toTypeId, v ); } if( mt->canCastTo( toTypeId ) ) { return mt->castTo( p, toTypeId, v ); } } if( toTypeId == mt->typeId() && mt->canConvertFrom( fromTypeId ) ) { found = true; return mt->convertFrom( v, fromTypeId, p ); } mt = mt->next_; } return false; } bool Data::canConvert( int fromTypeId, int toTypeId ) { const Data * mt = lh_first_info_; while( mt ) { if( fromTypeId == mt->typeId() ) { if( mt->canConvertTo( toTypeId ) ) return true; if( mt->canCastTo( toTypeId ) ) return true; } if( toTypeId == mt->typeId() && mt->canConvertFrom( fromTypeId ) ) return true; mt = mt->next_; } return false; } Data::Data(int typeId, equals_fn equals, lessThan_fn lessThan, castTo_fn castTo, convertTo_fn convertTo, convertFrom_fn convertFrom, canCastTo_fn canCastTo, canConvertTo_fn canConvertTo, canConvertFrom_fn canConvertFrom ) : typeId_( lh_lock_and_filter( typeId ) ), equals_( equals ), lessThan_( lessThan ), castTo_( castTo ), convertTo_( convertTo ), convertFrom_( convertFrom ), canCastTo_( canCastTo ), canConvertTo_( canConvertTo ), canConvertFrom_( canConvertFrom ), next_( typeId_ ? lh_first_info_ : 0 ) { if( typeId_ ) lh_first_info_ = this; lh_type_data_mutex_.unlock(); } } // namespace Type
void TConnection::lock(){mutex.lock();}
void CDeckLinkGLWidget::resizeGL (int width, int height) { mutex.lock(); glViewport(0, 0, width, height); mutex.unlock(); }
void TConnection::unlock(){mutex.unlock();}
FindSaneDevicesThread::~FindSaneDevicesThread() { s_mutexsane.lock(); wait(); s_mutexsane.unlock(); }
void River::generateImages(QVector<QImage> &images, QVector<QString> & stockNames, QMutex &imageMutex, Statistics & stats) { imageMutex.lock(); for(int imageIndex = 0; imageIndex < NUM_IMAGES; imageIndex++){ QColor color("black"); images[imageIndex].fill(color.rgb()); } for(int i = 0; i < p.getSize(); i++){ if(!p.hasWater[i]) { continue; } int x = p.pxcor[i]; int y = p.pycor[i]; QColor macroColor = getHeatMapColor(p.macro[i], stats.avgMacro, stats.maxMacro); QColor phytoColor = getHeatMapColor(p.phyto[i], stats.avgPhyto, stats.maxPhyto); QColor herbivoreColor = getHeatMapColor(p.herbivore[i], stats.avgHerbivore, stats.maxHerbivore); QColor waterDecompColor = getHeatMapColor(p.waterdecomp[i], stats.avgWaterDecomp, stats.maxWaterDecomp); QColor sedDecompColor = getHeatMapColor(p.seddecomp[i], stats.avgSedDecomp, stats.maxSedDecomp); QColor sedConsumerColor = getHeatMapColor(p.sedconsumer[i], stats.avgSedConsumer, stats.maxSedConsumer); QColor consumColor = getHeatMapColor(p.consumer[i], stats.avgConsum, stats.maxConsum); QColor DOCColor = getHeatMapColor(p.DOC[i], stats.avgDOC, stats.maxDOC); QColor POCColor = getHeatMapColor(p.POC[i], stats.avgPOC, stats.maxPOC); QColor detritusColor = getHeatMapColor(p.detritus[i], stats.avgDetritus, stats.maxDetritus); images[STOCK_MACRO].setPixel( x, y, macroColor.rgb()); images[STOCK_PHYTO].setPixel(x, y, phytoColor.rgb()); images[STOCK_HERBIVORE].setPixel(x, y, herbivoreColor.rgb()); images[STOCK_WATERDECOMP].setPixel( x, y, waterDecompColor.rgb()); images[STOCK_SEDDECOMP].setPixel(x, y, sedDecompColor.rgb()); images[STOCK_SEDCONSUMER].setPixel(x, y, sedConsumerColor.rgb()); images[STOCK_CONSUMER].setPixel(x, y, consumColor.rgb()); images[STOCK_DOC].setPixel(x, y, DOCColor.rgb()); images[STOCK_POC].setPixel(x, y, POCColor.rgb()); images[STOCK_DETRITUS].setPixel(x, y, detritusColor.rgb()); int patchCarbon = p.macro[i] + p.phyto[i] + p.herbivore[i] + p.waterdecomp[i] + p.seddecomp[i] + p.sedconsumer[i] + p.consumer[i] + p.DOC[i] + p.POC[i] + p.detritus[i]; QColor allCarbonColor = getHeatMapColor(patchCarbon, stats.avgCarbon, stats.maxCarbon); images[STOCK_ALL_CARBON].setPixel(x, y, allCarbonColor.rgb()); } //Due to the layout of the hydrofiles, the river will appear upside down if we don't flip it. for(int imageIndex = 0; imageIndex < NUM_IMAGES; imageIndex++){ images[imageIndex] = images[imageIndex].mirrored(false,true); } imageMutex.unlock(); QImageWriter writer; writer.setFormat("png"); for(int i = 0; i < NUM_IMAGES; i++){ QString date_time_str = QDateTime::currentDateTime().toString("_MMM_d_H_mm_ss"); QString fileName = "./results/images/" + stockNames[i] + date_time_str + ".png"; writer.setFileName(fileName); writer.write(images[i]); } }
void Core::run() { #ifdef DEBUG_CORE qlonglong debug; Mdebug.lock(); debug=++debugcounter; Mdebug.unlock(); qDebug()<<"core:run"<<" ID="<<debug; #endif //DEBUG_CORE bool last = false; LoadTask task; MtileLoadQueue.lock(); { if(tileLoadQueue.count() > 0) { task = tileLoadQueue.dequeue(); { last = (tileLoadQueue.count() == 0); #ifdef DEBUG_CORE qDebug()<<"TileLoadQueue: " << tileLoadQueue.count()<<" Point:"<<task.Pos.ToString()<<" ID="<<debug;; #endif //DEBUG_CORE } } } MtileLoadQueue.unlock(); if(task.HasValue()) if(loaderLimit.tryAcquire(1,OPMaps::Instance()->Timeout)) { MtileToload.lock(); --tilesToload; MtileToload.unlock(); #ifdef DEBUG_CORE qDebug()<<"loadLimit semaphore aquired "<<loaderLimit.available()<<" ID="<<debug<<" TASK="<<task.Pos.ToString()<<" "<<task.Zoom; #endif //DEBUG_CORE { #ifdef DEBUG_CORE qDebug()<<"task as value, begining get"<<" ID="<<debug;; #endif //DEBUG_CORE { Tile* m = Matrix.TileAt(task.Pos); if(m==0 || m->Overlays.count() == 0) { #ifdef DEBUG_CORE qDebug()<<"Fill empty TileMatrix: " + task.ToString()<<" ID="<<debug;; #endif //DEBUG_CORE Tile* t = new Tile(task.Zoom, task.Pos); QVector<MapType::Types> layers= OPMaps::Instance()->GetAllLayersOfType(GetMapType()); foreach(MapType::Types tl,layers) { int retry = 0; do { QByteArray img; // tile number inversion(BottomLeft -> TopLeft) for pergo maps if(tl == MapType::PergoTurkeyMap) { img = OPMaps::Instance()->GetImageFrom(tl, Point(task.Pos.X(), maxOfTiles.Height() - task.Pos.Y()), task.Zoom); } else // ok { #ifdef DEBUG_CORE qDebug()<<"start getting image"<<" ID="<<debug; #endif //DEBUG_CORE img = OPMaps::Instance()->GetImageFrom(tl, task.Pos, task.Zoom); #ifdef DEBUG_CORE qDebug()<<"Core::run:gotimage size:"<<img.count()<<" ID="<<debug<<" time="<<t.elapsed(); #endif //DEBUG_CORE } if(img.length()!=0) { Moverlays.lock(); { t->Overlays.append(img); #ifdef DEBUG_CORE qDebug()<<"Core::run append img:"<<img.length()<<" to tile:"<<t->GetPos().ToString()<<" now has "<<t->Overlays.count()<<" overlays"<<" ID="<<debug; #endif //DEBUG_CORE } Moverlays.unlock(); break; } else if(OPMaps::Instance()->RetryLoadTile > 0) { #ifdef DEBUG_CORE qDebug()<<"ProcessLoadTask: " << task.ToString()<< " -> empty tile, retry " << retry<<" ID="<<debug;; #endif //DEBUG_CORE { QWaitCondition wait; QMutex m; m.lock(); wait.wait(&m,500); } } } while(++retry < OPMaps::Instance()->RetryLoadTile); } if(t->Overlays.count() > 0) { Matrix.SetTileAt(task.Pos,t); emit OnNeedInvalidation(); #ifdef DEBUG_CORE qDebug()<<"Core::run add tile "<<t->GetPos().ToString()<<" to matrix index "<<task.Pos.ToString()<<" ID="<<debug; qDebug()<<"Core::run matrix index "<<task.Pos.ToString()<<" as tile with "<<Matrix.TileAt(task.Pos)->Overlays.count()<<" ID="<<debug; #endif //DEBUG_CORE } else { // emit OnTilesStillToLoad(tilesToload); delete t; t = 0; emit OnNeedInvalidation(); } // layers = null; } }
void mythread::readyRead() { //this will change int flag=0; QString::iterator it; frameData tempData; QByteArray stuff = socket->readAll(); qDebug() << stuff; QString stuffText,testName, msgTemp; stuffText.clear(); qDebug() << socketDescriptor << "Data in: " << stuff; if(stuff=="REG\n") // set client username internal to the thread. No need to do much else. { socket->write("ACK"); socket->flush(); socket->waitForReadyRead(); stuff=socket->readAll(); name=stuff; if(-1==socket->write("ACK"))//to finalize name registration. { qDebug() << "error2"; } socket->flush(); } //done...... much easier than before... wow. if(stuff=="REGJ\n") // set client username internal to the thread. No need to do much else. { socket->write("ACK\n"); socket->flush(); //socket->flush(); socket->waitForReadyRead(); stuff=socket->readAll(); name=stuff; if(-1==socket->write("ACK\n"))//to finalize name registration. { qDebug() << "error2"; } socket->flush(); } if(stuff=="MSG\n") //client would like to send a message. { qDebug() << socket->isOpen(); socket->waitForReadyRead(); stuff=socket->readAll(); qDebug() << stuff; msgTemp.clear(); msgTemp = '<'; msgTemp.append(name); msgTemp.append(">: "); msgTemp.append(stuff); msgTemp.append('\n'); lock->lock(); //I'm messing with the shared memory here... make sure to lock tempData.setData(msgTemp.toUtf8()); tempData.setFrame(*sysFrame); sendData->append(tempData); (*sysFrame)++; lock->unlock(); } }
void QHelpContentProvider::run() { QString title; QString link; int depth = 0; QHelpContentItem *item = 0; m_mutex.lock(); m_rootItem = new QHelpContentItem(QString(), QString(), 0); m_rootItems.enqueue(m_rootItem); QStringList atts = m_filterAttributes; const QStringList fileNames = m_helpEngine->orderedFileNameList; m_mutex.unlock(); foreach (const QString &dbFileName, fileNames) { m_mutex.lock(); if (m_abort) { m_abort = false; m_mutex.unlock(); break; } m_mutex.unlock(); QHelpDBReader reader(dbFileName, QHelpGlobal::uniquifyConnectionName(dbFileName + QLatin1String("FromQHelpContentProvider"), QThread::currentThread()), 0); if (!reader.init()) continue; foreach (const QByteArray& ba, reader.contentsForFilter(atts)) { if (ba.size() < 1) continue; int _depth = 0; bool _root = false; QStack<QHelpContentItem*> stack; QDataStream s(ba); for (;;) { s >> depth; s >> link; s >> title; if (title.isEmpty()) break; CHECK_DEPTH: if (depth == 0) { m_mutex.lock(); item = new QHelpContentItem(title, link, m_helpEngine->fileNameReaderMap.value(dbFileName), m_rootItem); m_rootItem->appendChild(item); m_mutex.unlock(); stack.push(item); _depth = 1; _root = true; } else { if (depth > _depth && _root) { _depth = depth; stack.push(item); } if (depth == _depth) { item = new QHelpContentItem(title, link, m_helpEngine->fileNameReaderMap.value(dbFileName), stack.top()); stack.top()->appendChild(item); } else if (depth < _depth) { stack.pop(); --_depth; goto CHECK_DEPTH; } } } } }
Worker(QObject * parent = 0) : QThread(parent) { m_started.lock(); }