Ticket #5604: DeviceReadBuffer-polltimeout.patch

File DeviceReadBuffer-polltimeout.patch, 5.5 KB (added by jppoet@…, 12 years ago)

limits the number of consecutive poll timeouts.

  • libs/libmythtv/DeviceReadBuffer.h

     
    5959    void IncrReadPointer(uint len);
    6060
    6161    bool HandlePausing(void);
    62     bool Poll(void) const;
     62    bool Poll(void);
    6363    uint WaitForUnused(uint bytes_needed) const;
    6464    uint WaitForUsed  (uint bytes_needed) const;
    6565
  • libs/libmythtv/DeviceReadBuffer.cpp

     
    8989
    9090void DeviceReadBuffer::Start(void)
    9191{
    92     lock.lock();
    93     bool was_running = running;
    94     lock.unlock();
     92    bool was_running;
     93
     94    {
     95        QMutexLocker locker(&lock);
     96        was_running = running;
     97        error = false;
     98    }
     99
    95100    if (was_running)
    96101    {
    97102        VERBOSE(VB_IMPORTANT, LOC_ERR + "Start(): Already running.");
     
    103108    {
    104109        VERBOSE(VB_IMPORTANT,
    105110                LOC_ERR + QString("Start(): pthread_create failed.") + ENO);
     111
     112        QMutexLocker locker(&lock);
    106113        error = true;
    107114    }
    108115}
     
    117124    used          = 0;
    118125    readPtr       = buffer;
    119126    writePtr      = buffer;
     127
     128    error         = false;
    120129}
    121130
    122131void DeviceReadBuffer::Stop(void)
    123132{
    124133    bool was_running = IsRunning();
    125     lock.lock();
    126     run = false;
    127     lock.unlock();
    128134
     135    {
     136        QMutexLocker locker(&lock);
     137        run = false;
     138    }
     139
    129140    if (!was_running)
    130141    {
    131142        VERBOSE(VB_IMPORTANT, LOC_ERR + "Stop(): Not running.");
     
    143154
    144155void DeviceReadBuffer::SetPaused(bool val)
    145156{
    146     lock.lock();
    147     paused = val;
    148     lock.unlock();
     157    {
     158        QMutexLocker locker(&lock);
     159        paused = val;
     160    }
     161
    149162    if (val)
    150163        pauseWait.wakeAll();
    151164    else
     
    233246{
    234247    uint      errcnt = 0;
    235248
    236     lock.lock();
    237     run     = true;
    238     running = true;
    239     lock.unlock();
     249    {
     250        QMutexLocker locker(&lock);
     251        run     = true;
     252        running = true;
     253    }
    240254
    241255    while (run)
    242256    {
     
    252266        if (using_poll && !Poll())
    253267            continue;
    254268
     269        {
     270            QMutexLocker locker(&lock);
     271            if (error)
     272            {
     273                VERBOSE(VB_RECORD, LOC + "fill_ringbuffer: error state");
     274                break;
     275            }
     276        }
     277
    255278        // Limit read size for faster return from read
    256279        size_t read_size =
    257280            min(dev_read_size, (size_t) WaitForUnused(TSPacket::SIZE));
     
    272295        }
    273296    }
    274297
    275     lock.lock();
     298    QMutexLocker locker(&lock);
    276299    running = false;
    277     lock.unlock();
    278300}
    279301
    280302bool DeviceReadBuffer::HandlePausing(void)
     
    297319    return true;
    298320}
    299321
    300 bool DeviceReadBuffer::Poll(void) const
     322bool DeviceReadBuffer::Poll(void)
    301323{
    302324#ifdef USING_MINGW
    303325#warning mingw DeviceReadBuffer::Poll
     
    306328    return false;
    307329#else
    308330    bool retval = true;
    309     while (true)
     331    uint timeout_cnt = 0;
     332
     333    for (;;)
    310334    {
    311335        struct pollfd polls;
    312336        polls.fd      = _stream_fd;
    313337        polls.events  = POLLIN;
    314338        polls.revents = 0;
    315339
    316         int ret = poll(&polls, 1 /*number of polls*/, 10 /*msec*/);
    317         if (IsPauseRequested() || !IsOpen() || !run)
     340        int ret = poll(&polls, 1 /*number of polls*/, 250 /*msec*/);
     341
     342        if (polls.revents & (POLLERR | POLLHUP | POLLNVAL))
    318343        {
     344            VERBOSE(VB_IMPORTANT, LOC + "poll error");
     345            error = true;
     346            return true;
     347        }
     348
     349        if (!run || !IsOpen() || IsPauseRequested())
     350        {
    319351            retval = false;
    320352            break; // are we supposed to pause, stop, etc.
    321353        }
    322354
    323355        if (ret > 0)
    324356            break; // we have data to read :)
    325         if ((-1 == ret) && (EOVERFLOW == errno))
    326             break; // we have an error to handle
    327 
    328         if ((-1 == ret) && ((EAGAIN == errno) || (EINTR  == errno)))
    329             continue; // errors that tell you to try again
    330         if (ret == 0)
    331             continue; // timed out, try again
    332 
    333         usleep(2500);
     357        if (ret < 0)
     358        {
     359            if ((EOVERFLOW == errno))
     360                break; // we have an error to handle
     361            if ((EAGAIN == errno) || (EINTR  == errno))
     362                continue; // errors that tell you to try again
     363            usleep(2500);
     364        }
     365        else //  ret == 0
     366        {
     367            if (++timeout_cnt > 9)
     368            {
     369                VERBOSE(VB_RECORD, LOC_ERR + "Poll giving up");
     370                QMutexLocker locker(&lock);
     371                error = true;
     372                return true;
     373            }
     374            if (timeout_cnt % 2)
     375                VERBOSE(VB_RECORD, LOC_ERR + QString("Poll timeout (%1)")
     376                        .arg(timeout_cnt));
     377        }
    334378    }
    335379    return retval;
    336380#endif //!USING_MINGW
     
    364408
    365409        if (++errcnt > 5)
    366410        {
    367             lock.lock();
     411            QMutexLocker locker(&lock);
     412            VERBOSE(VB_RECORD, LOC + "Too many errors.");
    368413            error = true;
    369             lock.unlock();
    370414            return false;
    371415        }
    372416
     
    380424            VERBOSE(VB_IMPORTANT, LOC +
    381425                    QString("End-Of-File? fd(%1)").arg(_stream_fd));
    382426
    383             lock.lock();
     427            QMutexLocker locker(&lock);
    384428            eof = true;
    385             lock.unlock();
    386 
    387429            return false;
    388430        }
    389431        usleep(500);