示例#1
0
void AppleRemote::run()
{
    threadRegister("AppleRemote");
    CFRunLoopRun();
    exec();  // prevent QThread exiting, by entering its run loop
    CFRunLoopStop(CFRunLoopGetCurrent());
    threadDeregister();
}
示例#2
0
void PreviewGenerator::run(void)
{
    threadRegister("PreviewGenerator");
    setPriority(QThread::LowPriority);
    Run();
    connect(this, SIGNAL(finished()),
            this, SLOT(deleteLater()));
    threadDeregister();
}
示例#3
0
 virtual void run(void)
 {
     threadRegister("Reconnect");
     if (gCoreContext->GetMasterHostPrefix().isEmpty())
         gCoreContext->dispatch(MythEvent(QString("RECONNECT_FAILURE")));
     else
         gCoreContext->dispatch(MythEvent(QString("RECONNECT_SUCCESS")));
     threadDeregister();
 }
示例#4
0
    void run()
    {
        threadRegister("ThemeExtract");
        extractZIP(m_srcFile, m_destDir);

        MythEvent *me =
             new MythEvent("THEME_INSTALLED", QStringList(m_srcFile));
        QCoreApplication::postEvent(m_parent, me);
        threadDeregister();
    }
示例#5
0
/// \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();
}
示例#6
0
    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();
    }
示例#7
0
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();
}
示例#8
0
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();
}
示例#9
0
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();
}
示例#10
0
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();
}
示例#11
0
/// \brief Runs ThreadedFileWriter::SyncLoop(void)
void TFWSyncThread::run(void)
{
    threadRegister("TFWSync");
    m_parent->SyncLoop();
    threadDeregister();
}
示例#12
0
void FirewireTableMonitorThread::run(void)
{
    threadRegister("FirewireTableMonitor");
    m_parent->RunTableMonitor();
    threadDeregister();
}
示例#13
0
/** \fn EITThread::run(void)
 *  \brief Thunk that allows scanner Qthread to
 *         call EITScanner::RunEventLoop().
 */
void EITThread::run(void)
{
    threadRegister("EIT");
    scanner->RunEventLoop();
    threadDeregister();
}
示例#14
0
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();
}
示例#15
0
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();
}
示例#16
0
void FileScannerThread::run()
{
    threadRegister("FileScanner");
    m_parent->doScan();
    threadDeregister();
}
示例#17
0
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();
}
示例#18
0
void IPTVTableMonitorThread::run(void)
{
    threadRegister("IPTVTableMonitor");
    m_parent->RunTableMonitor();
    threadDeregister();
}
示例#19
0
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();
}
示例#20
0
/** \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();
}
示例#21
0
 void run(void) 
 { 
     threadRegister("ProgramInfoLoader");
     m_cache.Load(m_updateUI); 
     threadDeregister();
 }
示例#22
0
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();
}