void AppleRemote::run() { threadRegister("AppleRemote"); CFRunLoopRun(); exec(); // prevent QThread exiting, by entering its run loop CFRunLoopStop(CFRunLoopGetCurrent()); threadDeregister(); }
void PreviewGenerator::run(void) { threadRegister("PreviewGenerator"); setPriority(QThread::LowPriority); Run(); connect(this, SIGNAL(finished()), this, SLOT(deleteLater())); threadDeregister(); }
virtual void run(void) { threadRegister("Reconnect"); if (gCoreContext->GetMasterHostPrefix().isEmpty()) gCoreContext->dispatch(MythEvent(QString("RECONNECT_FAILURE"))); else gCoreContext->dispatch(MythEvent(QString("RECONNECT_SUCCESS"))); threadDeregister(); }
void run() { threadRegister("ThemeExtract"); extractZIP(m_srcFile, m_destDir); MythEvent *me = new MythEvent("THEME_INSTALLED", QStringList(m_srcFile)); QCoreApplication::postEvent(m_parent, me); threadDeregister(); }
/// \brief Runs ThreadedFileWriter::DiskLoop(void) void TFWWriteThread::run(void) { threadRegister("TFWWrite"); #ifndef USING_MINGW // don't exit program if file gets larger than quota limit.. signal(SIGXFSZ, SIG_IGN); #endif m_parent->DiskLoop(); threadDeregister(); }
virtual void run(void) { threadRegister("RebuildSaver"); m_decoder->SavePositionMapDelta(m_first, m_last); QMutexLocker locker(&s_lock); s_cnt[m_decoder]--; if (!s_cnt[m_decoder]) s_wait.wakeAll(); threadDeregister(); }
void FetcherThread::run(void) { if (!m_dec) return; threadRegister("Fetcher"); VERBOSE(VB_PLAYBACK, LOC + QString("Starting Fetcher thread.")); m_dec->FetchFrames(); VERBOSE(VB_PLAYBACK, LOC + QString("Stopping Fetcher thread.")); threadDeregister(); }
void DVBStreamHandler::run(void) { threadRegister("DVBRead"); LOG(VB_RECORD, LOG_INFO, LOC + "run(): begin"); if (!SupportsTSMonitoring() && _allow_section_reader) RunSR(); else RunTS(); LOG(VB_RECORD, LOG_INFO, LOC + "run(): end"); threadDeregister(); }
void MythSystemSignalManager::run(void) { threadRegister("SystemSignalManager"); LOG(VB_GENERAL, LOG_INFO, "Starting process signal handler"); while( gCoreContext ) { usleep(50000); // sleep 50ms while( gCoreContext ) { // handle cleanup and signalling for closed processes listLock.lock(); if( msList.isEmpty() ) { listLock.unlock(); break; } MythSystemWindows *ms = msList.takeFirst(); listLock.unlock(); ms->m_parent->HandlePostRun(); if (ms->m_stdpipe[0]) writeThread->remove(ms->m_stdpipe[0]); CLOSE(ms->m_stdpipe[0]); if (ms->m_stdpipe[1]) readThread->remove(ms->m_stdpipe[1]); CLOSE(ms->m_stdpipe[1]); if (ms->m_stdpipe[2]) readThread->remove(ms->m_stdpipe[2]); CLOSE(ms->m_stdpipe[2]); if( ms->GetStatus() == GENERIC_EXIT_OK ) emit ms->finished(); else emit ms->error(ms->GetStatus()); ms->disconnect(); ms->Unlock(); if( ms->m_parent->doAutoCleanup() ) delete ms; } } threadDeregister(); }
void MythSystemIOHandler::run(void) { threadRegister(QString("SystemIOHandler%1").arg(m_read ? "R" : "W")); LOG(VB_GENERAL, LOG_INFO, QString("Starting IO manager (%1)") .arg(m_read ? "read" : "write")); QMutex mutex; while( gCoreContext ) { mutex.lock(); m_pWait.wait(&mutex); mutex.unlock(); while( gCoreContext ) { usleep(10000); // ~100x per second, for ~3MBps throughput m_pLock.lock(); if( m_pMap.isEmpty() ) { m_pLock.unlock(); break; } bool datafound = true; m_pLock.unlock(); while ( datafound && gCoreContext ) { m_pLock.lock(); datafound = false; PMap_t::iterator i, next; for( i = m_pMap.begin(); i != m_pMap.end(); i = next ) { next = i + 1; if( m_read ) datafound |= HandleRead(i.key(), i.value()); else datafound |= HandleWrite(i.key(), i.value()); } m_pLock.unlock(); } } } threadDeregister(); }
/// \brief Runs ThreadedFileWriter::SyncLoop(void) void TFWSyncThread::run(void) { threadRegister("TFWSync"); m_parent->SyncLoop(); threadDeregister(); }
void FirewireTableMonitorThread::run(void) { threadRegister("FirewireTableMonitor"); m_parent->RunTableMonitor(); threadDeregister(); }
/** \fn EITThread::run(void) * \brief Thunk that allows scanner Qthread to * call EITScanner::RunEventLoop(). */ void EITThread::run(void) { threadRegister("EIT"); scanner->RunEventLoop(); threadDeregister(); }
void ThumbGenerator::run() { threadRegister("ThumbGenerator"); while (moreWork()) { QString file, dir; bool isGallery; m_mutex.lock(); dir = m_directory; isGallery = m_isGallery; file = m_fileList.first(); if (!m_fileList.isEmpty()) m_fileList.pop_front(); m_mutex.unlock(); if (file.isEmpty()) continue; QString filePath = dir + QString("/") + file; QFileInfo fileInfo(filePath); if (!fileInfo.exists()) continue; if (isGallery) { if (fileInfo.isDir()) isGallery = checkGalleryDir(fileInfo); else isGallery = checkGalleryFile(fileInfo); } if (!isGallery) { QString cachePath = QString("%1%2.jpg").arg(getThumbcacheDir(dir)) .arg(file); QFileInfo cacheInfo(cachePath); if (cacheInfo.exists() && cacheInfo.lastModified() >= fileInfo.lastModified()) { continue; } else { // cached thumbnail not there or out of date QImage image; // Remove the old one if it exists if (cacheInfo.exists()) QFile::remove(cachePath); if (fileInfo.isDir()) loadDir(image, fileInfo); else loadFile(image, fileInfo); if (image.isNull()) continue; // give up; // if the file is a movie save the image to use as a screenshot if (GalleryUtil::IsMovie(fileInfo.filePath())) { QString screenshotPath = QString("%1%2-screenshot.jpg") .arg(getThumbcacheDir(dir)) .arg(file); image.save(screenshotPath, "JPEG", 95); } image = image.scaled(m_width,m_height, Qt::KeepAspectRatio, Qt::SmoothTransformation); image.save(cachePath, "JPEG", 95); // deep copies all over ThumbData *td = new ThumbData; td->directory = dir; td->fileName = file; td->thumb = image.copy(); // inform parent we have thumbnail ready for it QApplication::postEvent(m_parent, new ThumbGenEvent(td)); } } } threadDeregister(); }
void MythSocketThread::run(void) { threadRegister("Socket"); VERBOSE(VB_SOCKET, "MythSocketThread: readyread thread start"); QMutexLocker locker(&m_readyread_lock); m_readyread_started_wait.wakeAll(); while (m_readyread_run) { VERBOSE(VB_SOCKET|VB_EXTRA, "ProcessAddRemoveQueues"); ProcessAddRemoveQueues(); VERBOSE(VB_SOCKET|VB_EXTRA, "Construct FD_SET"); // construct FD_SET for all connected and unlocked sockets... int maxfd = -1; fd_set rfds; FD_ZERO(&rfds); QList<MythSocket*>::const_iterator it = m_readyread_list.begin(); for (; it != m_readyread_list.end(); ++it) { if (!(*it)->TryLock(false)) continue; if ((*it)->state() == MythSocket::Connected && !(*it)->m_notifyread) { FD_SET((*it)->socket(), &rfds); maxfd = std::max((*it)->socket(), maxfd); } (*it)->Unlock(false); } // There are no unlocked sockets, wait for event before we continue.. if (maxfd < 0) { VERBOSE(VB_SOCKET|VB_EXTRA, "Empty FD_SET, sleeping"); if (m_readyread_wait.wait(&m_readyread_lock)) VERBOSE(VB_SOCKET|VB_EXTRA, "Empty FD_SET, woken up"); else VERBOSE(VB_SOCKET|VB_EXTRA, "Empty FD_SET, timed out"); continue; } int rval = 0; if (m_readyread_pipe[0] >= 0) { // Clear out any pending pipe reads, we have already taken care of // this event above under the m_readyread_lock. char dummy[128]; if (m_readyread_pipe_flags[0] & O_NONBLOCK) { rval = ::read(m_readyread_pipe[0], dummy, 128); FD_SET(m_readyread_pipe[0], &rfds); maxfd = std::max(m_readyread_pipe[0], maxfd); } // also exit select on exceptions on same descriptors fd_set efds; memcpy(&efds, &rfds, sizeof(fd_set)); // The select waits forever for data, so if we need to process // anything else we need to write to m_readyread_pipe[1].. // We unlock the ready read lock, because we don't need it // and this will allow WakeReadyReadThread() to run.. m_readyread_lock.unlock(); VERBOSE(VB_SOCKET|VB_EXTRA, "Waiting on select.."); rval = select(maxfd + 1, &rfds, NULL, &efds, NULL); VERBOSE(VB_SOCKET|VB_EXTRA, "Got data on select"); m_readyread_lock.lock(); if (rval > 0 && FD_ISSET(m_readyread_pipe[0], &rfds)) { int ret = ::read(m_readyread_pipe[0], dummy, 128); if (ret < 0) { VERBOSE(VB_SOCKET|VB_EXTRA, "Strange.. failed to read event pipe"); } } } else { VERBOSE(VB_SOCKET|VB_EXTRA, "Waiting on select.. (no pipe)"); // also exit select on exceptions on same descriptors fd_set efds; memcpy(&efds, &rfds, sizeof(fd_set)); // Unfortunately, select on a pipe is not supported on all // platforms. So we fallback to a loop that instead times out // of select and checks for wakeAll event. while (!rval) { struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = kShortWait * 1000; rval = select(maxfd + 1, &rfds, NULL, &efds, &timeout); if (!rval) m_readyread_wait.wait(&m_readyread_lock, kShortWait); } VERBOSE(VB_SOCKET|VB_EXTRA, "Got data on select (no pipe)"); } if (rval <= 0) { if (rval == 0) { // Note: This should never occur when using pipes. When there // is no error there should be data in at least one fd.. VERBOSE(VB_SOCKET|VB_EXTRA, "MythSocketThread: select timeout"); } else VERBOSE(VB_SOCKET, "MythSocketThread: select returned error" + ENO); m_readyread_wait.wait(&m_readyread_lock, kShortWait); continue; } // ReadyToBeRead allows calls back into the socket so we need // to release the lock for a little while. // since only this loop updates m_readyread_list this is safe. m_readyread_lock.unlock(); // Actually read some data! This is a form of co-operative // multitasking so the ready read handlers should be quick.. uint downref_tm = 0; if (!m_readyread_downref_list.empty()) { VERBOSE(VB_SOCKET|VB_EXTRA, "Deleting stale sockets"); QTime tm = QTime::currentTime(); for (it = m_readyread_downref_list.begin(); it != m_readyread_downref_list.end(); ++it) { (*it)->DownRef(); } m_readyread_downref_list.clear(); downref_tm = tm.elapsed(); } VERBOSE(VB_SOCKET|VB_EXTRA, "Processing ready reads"); QMap<uint,uint> timers; QTime tm = QTime::currentTime(); it = m_readyread_list.begin(); for (; it != m_readyread_list.end() && m_readyread_run; ++it) { if (!(*it)->TryLock(false)) continue; int socket = (*it)->socket(); if (socket >= 0 && (*it)->state() == MythSocket::Connected && FD_ISSET(socket, &rfds)) { QTime rrtm = QTime::currentTime(); ReadyToBeRead(*it); timers[socket] = rrtm.elapsed(); } (*it)->Unlock(false); } if (VERBOSE_LEVEL_CHECK(VB_SOCKET|VB_EXTRA)) { QString rep = QString("Total read time: %1ms, on sockets") .arg(tm.elapsed()); QMap<uint,uint>::const_iterator it = timers.begin(); for (; it != timers.end(); ++it) rep += QString(" {%1,%2ms}").arg(it.key()).arg(*it); if (downref_tm) rep += QString(" {downref, %1ms}").arg(downref_tm); VERBOSE(VB_SOCKET|VB_EXTRA, QString("MythSocketThread: ") + rep); } m_readyread_lock.lock(); VERBOSE(VB_SOCKET|VB_EXTRA, "Reacquired ready read lock"); } VERBOSE(VB_SOCKET, "MythSocketThread: readyread thread exit"); threadDeregister(); }
void FileScannerThread::run() { threadRegister("FileScanner"); m_parent->doScan(); threadDeregister(); }
void SSDP::run() { fd_set read_set; struct timeval timeout; threadRegister("SSDP"); VERBOSE(VB_UPNP, "SSDP::Run - SSDP Thread Started." ); // ---------------------------------------------------------------------- // Listen for new Requests // ---------------------------------------------------------------------- while ( ! m_bTermRequested ) { int nMaxSocket = 0; FD_ZERO( &read_set ); for (uint nIdx = 0; nIdx < NumberOfSockets; nIdx++ ) { if (m_Sockets[nIdx] != NULL && m_Sockets[nIdx]->socket() >= 0) { FD_SET( m_Sockets[ nIdx ]->socket(), &read_set ); nMaxSocket = max( m_Sockets[ nIdx ]->socket(), nMaxSocket ); #if 0 if (m_Sockets[ nIdx ]->bytesAvailable() > 0) { VERBOSE(VB_IMPORTANT, QString("Found Extra data before " "select: %1").arg(nIdx)); ProcessData( m_Sockets[ nIdx ] ); } #endif } } timeout.tv_sec = 1; timeout.tv_usec = 0; if ( select( nMaxSocket + 1, &read_set, NULL, NULL, &timeout ) != -1) { for (int nIdx = 0; nIdx < (int)NumberOfSockets; nIdx++ ) { if (m_Sockets[nIdx] != NULL && m_Sockets[nIdx]->socket() >= 0) { if (FD_ISSET( m_Sockets[ nIdx ]->socket(), &read_set )) { #if 0 VERBOSE(VB_IMPORTANT, QString("FD_ISSET( %1 )") .arg(nIdx)); #endif ProcessData( m_Sockets[ nIdx ] ); } } } } } threadDeregister(); }
void IPTVTableMonitorThread::run(void) { threadRegister("IPTVTableMonitor"); m_parent->RunTableMonitor(); threadDeregister(); }
void MetadataDownload::run() { MetadataLookup* lookup; threadRegister("MetadataDownload"); while ((lookup = moreWork()) != NULL) { MetadataLookupList list; // Go go gadget Metadata Lookup if (lookup->GetType() == VID) { if (lookup->GetSeason() > 0 || lookup->GetEpisode() > 0) list = handleTelevision(lookup); else if (!lookup->GetSubtitle().isEmpty()) list = handleVideoUndetermined(lookup); else list = handleMovie(lookup); } // else if (lookup->GetType() == MUSIC) // list = handleMusic(lookup); else if (lookup->GetType() == GAME) list = handleGame(lookup); // inform parent we have lookup ready for it if (m_parent && list.count() >= 1) { // If there's only one result, don't bother asking // our parent about it, just add it to the back of // the queue in GETDATA mode. if (list.count() == 1 && list.at(0)->GetStep() == SEARCH) { MetadataLookup *newlookup = list.takeFirst(); newlookup->SetStep(GETDATA); prependLookup(newlookup); continue; } // If we're in automatic mode, we need to make // these decisions on our own. Pass to title match. if (list.at(0)->GetAutomatic() && list.count() > 1) { if (!findBestMatch(list, lookup->GetTitle())) QCoreApplication::postEvent(m_parent, new MetadataLookupFailure(MetadataLookupList() << lookup)); continue; } VERBOSE(VB_GENERAL, QString("Returning Metadata Results: %1 %2 %3") .arg(lookup->GetTitle()).arg(lookup->GetSeason()) .arg(lookup->GetEpisode())); QCoreApplication::postEvent(m_parent, new MetadataLookupEvent(list)); } else { list.append(lookup); QCoreApplication::postEvent(m_parent, new MetadataLookupFailure(list)); } } threadDeregister(); }
/** \fn HDHRStreamHandler::run(void) * \brief Reads HDHomeRun socket for tables & data */ void HDHRStreamHandler::run(void) { threadRegister("HDHRStreamHandler"); /* Create TS socket. */ if (!hdhomerun_device_stream_start(_hdhomerun_device)) { LOG(VB_GENERAL, LOG_ERR, LOC + "Starting recording (set target failed). Aborting."); _error = true; threadDeregister(); return; } hdhomerun_device_stream_flush(_hdhomerun_device); SetRunning(true, false, false); /* Calculate buffer size */ uint buffersize = gCoreContext->GetNumSetting( "HDRingbufferSize", 50 * TSPacket::kSize) * 1024; buffersize /= VIDEO_DATA_PACKET_SIZE; buffersize *= VIDEO_DATA_PACKET_SIZE; buffersize = max(49 * TSPacket::kSize * 128, buffersize); LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): begin"); int remainder = 0; while (_running_desired && !_error) { UpdateFiltersFromStreamData(); UpdateFilters(); size_t read_size = 64 * 1024; // read about 64KB read_size /= VIDEO_DATA_PACKET_SIZE; read_size *= VIDEO_DATA_PACKET_SIZE; size_t data_length; unsigned char *data_buffer = hdhomerun_device_stream_recv( _hdhomerun_device, read_size, &data_length); if (!data_buffer) { usleep(5000); continue; } // Assume data_length is a multiple of 188 (packet size) _listener_lock.lock(); if (_stream_data_list.empty()) { _listener_lock.unlock(); continue; } StreamDataList::const_iterator sit = _stream_data_list.begin(); for (; sit != _stream_data_list.end(); ++sit) remainder = sit.key()->ProcessData(data_buffer, data_length); _listener_lock.unlock(); if (remainder != 0) { LOG(VB_RECORD, LOG_INFO, LOC + QString("RunTS(): data_length = %1 remainder = %2") .arg(data_length).arg(remainder)); } } LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "shutdown"); RemoveAllPIDFilters(); hdhomerun_device_stream_stop(_hdhomerun_device); LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "end"); SetRunning(false, false, false); threadDeregister(); }
void run(void) { threadRegister("ProgramInfoLoader"); m_cache.Load(m_updateUI); threadDeregister(); }
void MythSystemManager::run(void) { threadRegister("SystemManager"); LOG(VB_GENERAL, LOG_INFO, "Starting process manager"); // gCoreContext is set to NULL during shutdown, and we need this thread to // exit during shutdown. while( gCoreContext ) { // 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 MythSystemWindows *ms = m_pMap.take(child); ChildListRebuild(); m_mapLock.unlock(); 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(NULL); 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(); threadDeregister(); }