Ticket #5604: DeviceReadBuffer-polltimeout.2.patch

File DeviceReadBuffer-polltimeout.2.patch, 5.4 KB (added by jppoet@…, 11 years ago)

Updated patch for current trunk

  • 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

     
    9090
    9191void DeviceReadBuffer::Start(void)
    9292{
    93     lock.lock();
    94     bool was_running = running;
    95     lock.unlock();
     93    bool was_running;
     94
     95    {
     96        QMutexLocker locker(&lock);
     97        was_running = running;
     98        error = false;
     99    }
     100
    96101    if (was_running)
    97102    {
    98103        VERBOSE(VB_IMPORTANT, LOC_ERR + "Start(): Already running.");
     
    104109    {
    105110        VERBOSE(VB_IMPORTANT,
    106111                LOC_ERR + QString("Start(): pthread_create failed.") + ENO);
     112
     113        QMutexLocker locker(&lock);
    107114        error = true;
    108115    }
    109116}
     
    118125    used          = 0;
    119126    readPtr       = buffer;
    120127    writePtr      = buffer;
     128
     129    error         = false;
    121130}
    122131
    123132void DeviceReadBuffer::Stop(void)
    124133{
    125134    bool was_running = IsRunning();
    126     lock.lock();
    127     run = false;
    128     lock.unlock();
    129135
    130136    if (!was_running)
    131137    {
    132         VERBOSE(VB_IMPORTANT, LOC_ERR + "Stop(): Not running.");
     138        VERBOSE(VB_IMPORTANT, LOC + "Stop(): Not running.");
    133139        return;
    134140    }
    135141
     142    {
     143        QMutexLocker locker(&lock);
     144        run = false;
     145    }
     146
    136147    pthread_join(thread, NULL);
    137148}
    138149
     
    229240{
    230241    uint      errcnt = 0;
    231242
    232     lock.lock();
    233     run     = true;
    234     running = true;
    235     lock.unlock();
     243    {
     244        QMutexLocker locker(&lock);
     245        run     = true;
     246        running = true;
     247    }
    236248
    237249    while (run)
    238250    {
     
    248260        if (using_poll && !Poll())
    249261            continue;
    250262
     263        {
     264            QMutexLocker locker(&lock);
     265            if (error)
     266            {
     267                VERBOSE(VB_RECORD, LOC + "fill_ringbuffer: error state");
     268                break;
     269            }
     270        }
     271
    251272        // Limit read size for faster return from read
    252273        size_t read_size =
    253274            min(dev_read_size, (size_t) WaitForUnused(TSPacket::SIZE));
     
    268289        }
    269290    }
    270291
    271     lock.lock();
    272     running = false;
    273     lock.unlock();
     292    {
     293        QMutexLocker locker(&lock);
     294        running = false;
     295    }
    274296}
    275297
    276298bool DeviceReadBuffer::HandlePausing(void)
     
    293315    return true;
    294316}
    295317
    296 bool DeviceReadBuffer::Poll(void) const
     318bool DeviceReadBuffer::Poll(void)
    297319{
    298320#ifdef USING_MINGW
    299321#warning mingw DeviceReadBuffer::Poll
     
    302324    return false;
    303325#else
    304326    bool retval = true;
    305     while (true)
     327    uint timeout_cnt = 0;
     328
     329    for (;;)
    306330    {
    307331        struct pollfd polls;
    308332        polls.fd      = _stream_fd;
    309333        polls.events  = POLLIN;
    310334        polls.revents = 0;
    311335
    312         int ret = poll(&polls, 1 /*number of polls*/, 10 /*msec*/);
    313         if (IsPauseRequested() || !IsOpen() || !run)
     336        int ret = poll(&polls, 1 /*number of polls*/, 250 /*msec*/);
     337
     338        if (polls.revents & (POLLERR | POLLHUP | POLLNVAL))
    314339        {
     340            VERBOSE(VB_IMPORTANT, LOC + "poll error");
     341            error = true;
     342            return true;
     343        }
     344
     345        if (!run || !IsOpen() || IsPauseRequested())
     346        {
    315347            retval = false;
    316348            break; // are we supposed to pause, stop, etc.
    317349        }
    318350
    319351        if (ret > 0)
    320352            break; // we have data to read :)
    321         if ((-1 == ret) && (EOVERFLOW == errno))
    322             break; // we have an error to handle
    323 
    324         if ((-1 == ret) && ((EAGAIN == errno) || (EINTR  == errno)))
    325             continue; // errors that tell you to try again
    326         if (ret == 0)
    327             continue; // timed out, try again
    328 
    329         usleep(2500);
     353        if (ret < 0)
     354        {
     355            if ((EOVERFLOW == errno))
     356                break; // we have an error to handle
     357            if ((EAGAIN == errno) || (EINTR  == errno))
     358                continue; // errors that tell you to try again
     359            usleep(2500);
     360        }
     361        else //  ret == 0
     362        {
     363            if (++timeout_cnt > 9)
     364            {
     365                VERBOSE(VB_RECORD, LOC_ERR + "Poll giving up");
     366                QMutexLocker locker(&lock);
     367                error = true;
     368                return true;
     369            }
     370            if (timeout_cnt % 2)
     371                VERBOSE(VB_RECORD, LOC_ERR + QString("Poll timeout (%1)")
     372                        .arg(timeout_cnt));
     373        }
    330374    }
    331375    return retval;
    332376#endif //!USING_MINGW
     
    360404
    361405        if (++errcnt > 5)
    362406        {
    363             lock.lock();
     407            QMutexLocker locker(&lock);
     408            VERBOSE(VB_RECORD, LOC + "Too many errors.");
    364409            error = true;
    365             lock.unlock();
    366410            return false;
    367411        }
    368412
     
    376420            VERBOSE(VB_IMPORTANT, LOC +
    377421                    QString("End-Of-File? fd(%1)").arg(_stream_fd));
    378422
    379             lock.lock();
     423            QMutexLocker locker(&lock);
    380424            eof = true;
    381             lock.unlock();
    382 
    383425            return false;
    384426        }
    385427        usleep(500);