Ticket #12045: 12045-try2.diff

File 12045-try2.diff, 8.6 KB (added by JYA, 6 years ago)

another attempted fix

  • mythtv/libs/libmythbase/threadedfilewriter.cpp

    diff --git a/mythtv/libs/libmythbase/threadedfilewriter.cpp b/mythtv/libs/libmythbase/threadedfilewriter.cpp
    index aa2fd9d..832fdc8 100644
    a b uint ThreadedFileWriter::Write(const void *data, uint count) 
    288288        left    -= towrite;
    289289    }
    290290
    291     LOG(VB_FILE, LOG_DEBUG, LOC + QString("Write(*, %1) total %2 cnt %3")
    292             .arg(count,4).arg(totalBufferUse).arg(writeBuffers.size()));
     291        //LOG(VB_FILE, LOG_DEBUG, LOC + QString("Write(*, %1) total %2 cnt %3")
     292        //    .arg(count,4).arg(totalBufferUse).arg(writeBuffers.size()));
    293293
    294294    return count;
    295295}
    void ThreadedFileWriter::DiskLoop(void) 
    425425    MythTimer minWriteTimer;
    426426    minWriteTimer.start();
    427427
     428    uint64_t total_written = 0LL;
     429
    428430    while (!in_dtor)
    429431    {
    430432        if (ignore_writes)
    void ThreadedFileWriter::DiskLoop(void) 
    518520            else
    519521            {
    520522                tot += ret;
     523                total_written += ret;
     524                LOG(VB_FILE, LOG_DEBUG, LOC + QString("total written so far: %1 bytes").arg(total_written));
    521525            }
    522526
    523527            locker.relock();
    bool ThreadedFileWriter::SetBlocking(bool block) 
    604608    bool old = m_blocking;
    605609    m_blocking = block;
    606610    return old;
    607 }
    608  No newline at end of file
     611}
  • mythtv/libs/libmythtv/fileringbuffer.cpp

    diff --git a/mythtv/libs/libmythtv/fileringbuffer.cpp b/mythtv/libs/libmythtv/fileringbuffer.cpp
    index 2548703..0cb192f 100644
    a b  
    44// POSIX C headers
    55#include <sys/types.h>
    66#include <sys/time.h>
     7#include <sys/stat.h>
    78#include <unistd.h>
    89#include <fcntl.h>
    910
    bool FileRingBuffer::IsOpen(void) const 
    437438 */
    438439int FileRingBuffer::safe_read(int fd, void *data, uint sz)
    439440{
    440     int ret;
     441    int ret, ret_select;
    441442    unsigned tot = 0;
    442443    unsigned errcnt = 0;
    443444    unsigned zerocnt = 0;
    int FileRingBuffer::safe_read(int fd, void *data, uint sz) 
    452453    if (stopreads)
    453454        return 0;
    454455
     456    MythTimer t;
     457    fd_set rfds;
     458    struct timeval tv;
     459    struct stat sb;
     460    off_t current_pos = internalreadpos;
     461
     462    t.start();
     463
    455464    while (tot < sz)
    456465    {
    457         ret = read(fd2, (char *)data + tot, sz - tot);
    458         if (ret < 0)
     466        /* Wait up to 500 millisecond for a read. */
     467        tv.tv_sec  = 0;
     468        tv.tv_usec = 500 * 1000;
     469        FD_ZERO(&rfds);
     470        FD_SET(fd2, &rfds);
     471
     472        ret_select = select(fd2 + 1, &rfds, NULL, NULL, &tv);
     473        if (ret_select == -1)
    459474        {
    460             if (errno == EAGAIN)
    461                 continue;
    462 
    463             LOG(VB_GENERAL, LOG_ERR,
    464                 LOC + "File I/O problem in 'safe_read()'" + ENO);
    465 
    466             errcnt++;
    467             numfailures++;
    468             if (errcnt == 3)
    469                 break;
     475            LOG(VB_FILE, LOG_ERR, LOC + "select() errored");
     476            break;
    470477        }
    471         else if (ret > 0)
     478        else if (ret_select)
    472479        {
    473             tot += ret;
    474         }
     480            // check that we have some data to read, so we never read past
     481            // the end of file
     482            off_t toread = sz - tot;
    475483
    476         if (oldfile)
    477             break;
     484            ret = fstat(fd2, &sb);
     485            if (ret == 0)
     486            {
     487                if (current_pos >= sb.st_size)
     488                {
     489                    // simulate a EOF return
     490                    ret = 0;
     491                }
     492                else
     493                {
     494                    toread = min(sb.st_size - current_pos, toread);
     495                    LOG(VB_FILE, LOG_DEBUG, LOC +
     496                        QString("read(%1) -- begin").arg(toread));
     497                    ret = read(fd2, (char *)data + tot, toread);
     498                    LOG(VB_FILE, LOG_DEBUG, LOC +
     499                        QString("read(%1) -> %2 end").arg(toread).arg(ret));
     500                }
     501            }
    478502
    479         if (ret == 0) // EOF returns 0
    480         {
    481             if (tot > 0)
    482                 break;
     503            if (ret < 0)
     504            {
     505                if (errno == EAGAIN)
     506                {
     507                    continue;
     508                }
    483509
    484             zerocnt++;
     510                LOG(VB_GENERAL, LOG_ERR,
     511                    LOC + "File I/O problem in 'safe_read()'" + ENO);
    485512
    486             // 0.36 second timeout for livetvchain with usleep(60000),
    487             // or 2.4 seconds if it's a new file less than 30 minutes old.
    488             if (zerocnt >= (livetvchain ? 6 : 40))
     513                errcnt++;
     514                numfailures++;
     515                if (errcnt == 3)
     516                    break;
     517            }
     518            else if (ret > 0)
    489519            {
    490                 break;
     520                tot += ret;
     521                current_pos += tot;
     522            }
     523            else if (ret == 0) // EOF returns 0
     524            {
     525                if (tot > 0)
     526                    break;
     527
     528                zerocnt++;
     529
     530                // 0.36 second timeout for livetvchain with usleep(60000),
     531                // or 2.4 seconds if it's a new file less than 30 minutes old.
     532                if (zerocnt >= (livetvchain ? 6 : 40))
     533                {
     534                    break;
     535                }
     536                if (tot < sz)
     537                    usleep(60000);
    491538            }
    492539        }
     540        else
     541        {
     542            LOG(VB_FILE, LOG_DEBUG,
     543                LOC + QString("Nothing to read for %1ms").arg(t.elapsed()));
     544            if (tot > 0)
     545                break;
     546        }
     547
     548        if (oldfile)
     549            break;
     550
    493551        if (stopreads)
    494552            break;
    495         if (tot < sz)
    496             usleep(60000);
    497553    }
    498554    return tot;
    499555}
  • mythtv/libs/libmythtv/ringbuffer.cpp

    diff --git a/mythtv/libs/libmythtv/ringbuffer.cpp b/mythtv/libs/libmythtv/ringbuffer.cpp
    index cbca8a6..45609cd 100644
    a b void RingBuffer::run(void) 
    769769        if (PauseAndWait())
    770770        {
    771771            ignore_for_read_timing = true;
     772            LOG(VB_FILE, LOG_DEBUG, LOC + "run: PauseAndWait Not reading continuing");
    772773            continue;
    773774        }
    774775
    775776        long long totfree = ReadBufFree();
    776777
    777778        const uint KB32 = 32*1024;
     779
     780//        if (totfree > ThreadedFileWriter::GetDefaultWriteBufferMinWriteSize())
     781//        {
     782//            totfree = ThreadedFileWriter::GetDefaultWriteBufferMinWriteSize();
     783//        }
     784
    778785        // These are conditions where we don't want to go through
    779786        // the loop if they are true.
    780787        if (((totfree < KB32) && readsallowed) ||
    void RingBuffer::run(void) 
    783790            ignore_for_read_timing |=
    784791                (ignorereadpos >= 0) || commserror || stopreads;
    785792            generalWait.wait(&rwlock, (stopreads) ? 50 : 1000);
     793            LOG(VB_FILE, LOG_DEBUG, LOC + QString("run: Not reading continuing: totfree(%1) readsallowed(%2) ignorereadpos(%3) commserror(%4) stopreads(%5)")
     794                .arg(totfree).arg(readsallowed).arg(ignorereadpos).arg(commserror).arg(stopreads));
    786795            continue;
    787796        }
    788797
    void RingBuffer::run(void) 
    898907                }
    899908                rbwlock.unlock();
    900909                poslock.unlock();
     910
     911                LOG(VB_FILE, LOG_DEBUG, LOC + QString("total read so far: %1 bytes").arg(internalreadpos));
     912               
    901913            }
    902914        }
     915        else
     916        {
     917            LOG(VB_FILE, LOG_DEBUG, LOC + QString("We are not reading anything (totfree: %1 commserror:%2 ateof:%3 setswitchtonext:%4").arg(totfree).arg(commserror).arg(ateof).arg(setswitchtonext));
     918        }
    903919
    904920        int used = bufferSize - ReadBufFree();
    905921
    bool RingBuffer::WaitForAvail(int count) 
    10841100            int elapsed = t.elapsed();
    10851101            if (elapsed > 500 && low_buffers && avail >= fill_min)
    10861102                count = avail;
    1087             else if  (((elapsed > 250) && (elapsed < 500))  ||
    1088                      ((elapsed >  500) && (elapsed < 750))  ||
     1103            else if  (((elapsed > 500) && (elapsed < 750))  ||
    10891104                     ((elapsed > 1000) && (elapsed < 1250)) ||
    10901105                     ((elapsed > 2000) && (elapsed < 2250)) ||
    10911106                     ((elapsed > 4000) && (elapsed < 4250)) ||
    10921107                     ((elapsed > 8000) && (elapsed < 8250)) ||
    10931108                     ((elapsed > 9000)))
    10941109            {
     1110                LOG(VB_FILE, LOG_DEBUG,
     1111                    LOC + QString("used = %1").arg(bufferSize - ReadBufFree()));
    10951112                LOG(VB_GENERAL, LOG_INFO, LOC + "Waited " +
    10961113                    QString("%1").arg((elapsed / 250) * 0.25f, 3, 'f', 1) +
    10971114                    " seconds for data \n\t\t\tto become available..." +