Ticket #12045: 12045.diff

File 12045.diff, 11.4 KB (added by JYA, 6 years ago)

Attempted fix

  • mythtv/libs/libmythbase/threadedfilewriter.cpp

    diff --git a/mythtv/libs/libmythbase/threadedfilewriter.cpp b/mythtv/libs/libmythbase/threadedfilewriter.cpp
    index aa2fd9d..deec603 100644
    a b void TFWWriteThread::run(void) 
    3232    RunEpilog();
    3333}
    3434
    35 /// \brief Runs ThreadedFileWriter::SyncLoop(void)
    36 void TFWSyncThread::run(void)
    37 {
    38     RunProlog();
    39     m_parent->SyncLoop();
    40     RunEpilog();
    41 }
    42 
    4335const uint ThreadedFileWriter::kMaxBufferSize   = 8 * 1024 * 1024;
    4436const uint ThreadedFileWriter::kMinWriteSize    = 64 * 1024;
    4537const uint ThreadedFileWriter::kMaxBlockSize    = 1 * 1024 * 1024;
    const uint ThreadedFileWriter::kMaxBlockSize = 1 * 1024 * 1024; 
    5042 *   This class allows us manage the buffering when writing to
    5143 *   disk. We write to the kernel image of the disk using one
    5244 *   thread, and sync the kernel's image of the disk to hardware
    53  *   using another thread. The goal here so to block as little as
     45 *   at most every seconds. The goal here so to block as little as
    5446 *   possible when the classes using this class want to add data
    5547 *   to the stream.
    5648 */
    ThreadedFileWriter::ThreadedFileWriter(const QString &fname, 
    6860    ignore_writes(false),                tfw_min_write_size(kMinWriteSize),
    6961    totalBufferUse(0),
    7062    // threads
    71     writeThread(NULL),                   syncThread(NULL),
     63    writeThread(NULL),
    7264    m_warned(false),                     m_blocking(false)
    7365{
    7466    filename.detach();
    bool ThreadedFileWriter::ReOpen(QString newFilename) 
    8880
    8981    if (fd >= 0)
    9082    {
     83        Sync();
    9184        close(fd);
    9285        fd = -1;
    9386    }
    bool ThreadedFileWriter::Open(void) 
    135128            writeThread->start();
    136129        }
    137130
    138         if (!syncThread)
    139         {
    140             syncThread = new TFWSyncThread(this);
    141             syncThread->start();
    142         }
    143 
    144131        return true;
    145132    }
    146133}
    ThreadedFileWriter::~ThreadedFileWriter() 
    155142    {  /* tell child threads to exit */
    156143        QMutexLocker locker(&buflock);
    157144        in_dtor = true;
    158         bufferSyncWait.wakeAll();
    159145        bufferHasData.wakeAll();
    160146    }
    161147
    ThreadedFileWriter::~ThreadedFileWriter() 
    178164        emptyBuffers.pop_front();
    179165    }
    180166
    181     if (syncThread)
    182     {
    183         syncThread->wait();
    184         delete syncThread;
    185         syncThread = NULL;
    186     }
    187 
    188167    if (fd >= 0)
    189168    {
     169        Sync();
    190170        close(fd);
    191171        fd = -1;
    192172    }
    void ThreadedFileWriter::Flush(void) 
    365345 */
    366346void ThreadedFileWriter::Sync(void)
    367347{
     348    LOG(VB_FILE, LOG_INFO, LOC + "Sync() called");
     349
    368350    if (fd >= 0)
    369351    {
    370352#if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
    void ThreadedFileWriter::SetWriteBufferMinWriteSize(uint newMinSize) 
    390372    bufferHasData.wakeAll();
    391373}
    392374
    393 /** \fn ThreadedFileWriter::SyncLoop(void)
    394  *  \brief The thread run method that calls Sync(void).
    395  */
    396 void ThreadedFileWriter::SyncLoop(void)
    397 {
    398     QMutexLocker locker(&buflock);
    399     while (!in_dtor)
    400     {
    401         locker.unlock();
    402 
    403         Sync();
    404 
    405         locker.relock();
    406         bufferSyncWait.wait(&buflock, 1000);
    407     }
    408 }
    409 
    410375/** \fn ThreadedFileWriter::DiskLoop(void)
    411376 *  \brief The thread run method that actually calls writes to disk.
    412377 */
    void ThreadedFileWriter::DiskLoop(void) 
    422387    // Even if the bytes buffered is less than the minimum write
    423388    // size we do want to write to the OS buffers periodically.
    424389    // This timer makes sure we do.
    425     MythTimer minWriteTimer;
     390    MythTimer minWriteTimer, lastSyncTimer;
    426391    minWriteTimer.start();
     392    lastSyncTimer.start();
    427393
    428394    while (!in_dtor)
    429395    {
    void ThreadedFileWriter::DiskLoop(void) 
    482448        uint tot = 0;
    483449        uint errcnt = 0;
    484450
    485         LOG(VB_FILE, LOG_DEBUG, LOC + QString("write(%1) cnt %2 total %3")
     451        LOG(VB_FILE, LOG_INFO, LOC + QString("write(%1) cnt %2 total %3")
    486452                .arg(sz).arg(writeBuffers.size())
    487453                .arg(totalBufferUse));
    488454
    void ThreadedFileWriter::DiskLoop(void) 
    526492                bufferHasData.wait(locker.mutex(), 50);
    527493        }
    528494
     495        if (lastSyncTimer.elapsed() >= 1000)
     496        {
     497            locker.unlock();
     498            Sync();
     499            locker.relock();
     500            lastSyncTimer.restart();
     501        }
     502
    529503        //////////////////////////////////////////
    530504
    531505        buf->lastUsed = MythDate::current();
    bool ThreadedFileWriter::SetBlocking(bool block) 
    604578    bool old = m_blocking;
    605579    m_blocking = block;
    606580    return old;
    607 }
    608  No newline at end of file
     581}
  • mythtv/libs/libmythbase/threadedfilewriter.h

    diff --git a/mythtv/libs/libmythbase/threadedfilewriter.h b/mythtv/libs/libmythbase/threadedfilewriter.h
    index 1142d27..e06fc29 100644
    a b class TFWWriteThread : public MThread 
    2828    ThreadedFileWriter *m_parent;
    2929};
    3030
    31 class TFWSyncThread : public MThread
    32 {
    33   public:
    34     TFWSyncThread(ThreadedFileWriter *p) : MThread("TFWSync"), m_parent(p) {}
    35     virtual ~TFWSyncThread() { wait(); m_parent = NULL; }
    36     virtual void run(void);
    37   private:
    38     ThreadedFileWriter *m_parent;
    39 };
    40 
    4131class MBASE_PUBLIC ThreadedFileWriter
    4232{
    4333    friend class TFWWriteThread;
    44     friend class TFWSyncThread;
     34
    4535  public:
    4636    ThreadedFileWriter(const QString &fname, int flags, mode_t mode);
    4737    ~ThreadedFileWriter();
    class MBASE_PUBLIC ThreadedFileWriter 
    6050
    6151  protected:
    6252    void DiskLoop(void);
    63     void SyncLoop(void);
    6453    void TrimEmptyBuffers(void);
    6554
    6655  private:
    class MBASE_PUBLIC ThreadedFileWriter 
    9079
    9180    // threads
    9281    TFWWriteThread *writeThread;
    93     TFWSyncThread  *syncThread;
    9482
    9583    // wait conditions
    9684    QWaitCondition  bufferEmpty;
    9785    QWaitCondition  bufferHasData;
    98     QWaitCondition  bufferSyncWait;
    9986    QWaitCondition  bufferWasFreed;
    10087
    10188    // constants
  • mythtv/libs/libmythtv/fileringbuffer.cpp

    diff --git a/mythtv/libs/libmythtv/fileringbuffer.cpp b/mythtv/libs/libmythtv/fileringbuffer.cpp
    index 2548703..3c7cc92 100644
    a b int FileRingBuffer::safe_read(int fd, void *data, uint sz) 
    454454
    455455    while (tot < sz)
    456456    {
     457        LOG(VB_FILE, LOG_DEBUG, LOC +
     458            QString("read(%1) -- begin").arg(sz));
    457459        ret = read(fd2, (char *)data + tot, sz - tot);
     460        LOG(VB_FILE, LOG_DEBUG, LOC +
     461            QString("read(%1) -> %2 end").arg(sz).arg(ret));
     462
    458463        if (ret < 0)
    459464        {
    460465            if (errno == EAGAIN)
  • mythtv/libs/libmythtv/ringbuffer.cpp

    diff --git a/mythtv/libs/libmythtv/ringbuffer.cpp b/mythtv/libs/libmythtv/ringbuffer.cpp
    index cbca8a6..5dbd48f 100644
    a b void RingBuffer::CalcReadAheadThresh(void) 
    348348    uint estbitrate = 0;
    349349
    350350    readsallowed   = false;
     351    LOG(VB_FILE, LOG_INFO, LOC +
     352        "CalcReadAheadThresh: readsallowed set to false.");
    351353    readblocksize  = max(readblocksize, CHUNK);
    352354
    353355    // loop without sleeping if the buffered data is less than this
    void RingBuffer::ResetReadAhead(long long newinternal) 
    484486    internalreadpos = newinternal;
    485487    ateof = false;
    486488    readsallowed = false;
     489    LOG(VB_FILE, LOG_INFO, LOC +
     490        "ResetReadAhead: readsallowed set to false.");
    487491    setswitchtonext = false;
    488492    generalWait.wakeAll();
    489493
    void RingBuffer::run(void) 
    762766
    763767    LOG(VB_FILE, LOG_INFO, LOC +
    764768        QString("Initial readblocksize %1K & fill_min %2K")
    765             .arg(readblocksize/1024).arg(fill_min/1024));
     769        .arg(readblocksize/1024).arg(fill_min/1024));
    766770
    767771    while (readaheadrunning)
    768772    {
    769773        if (PauseAndWait())
    770774        {
    771775            ignore_for_read_timing = true;
     776            LOG(VB_FILE, LOG_DEBUG, LOC + "run: PauseAndWait Not reading continuing");
    772777            continue;
    773778        }
    774779
    void RingBuffer::run(void) 
    783788            ignore_for_read_timing |=
    784789                (ignorereadpos >= 0) || commserror || stopreads;
    785790            generalWait.wait(&rwlock, (stopreads) ? 50 : 1000);
     791            LOG(VB_FILE, LOG_DEBUG, LOC + "run: Not reading continuing");
    786792            continue;
    787793        }
    788794
    void RingBuffer::run(void) 
    843849            ignore_for_read_timing = (totfree < readblocksize) ? true : false;
    844850            lastread = now;
    845851
     852            LOG(VB_FILE, LOG_INFO, LOC + "run(): rbwlock.lockForRead() start");
    846853            rbwlock.lockForRead();
     854            LOG(VB_FILE, LOG_INFO, LOC + "run(): rbwlock.lockForRead() done");
    847855            if (rbwpos + totfree > bufferSize)
    848856            {
    849857                totfree = bufferSize - rbwpos;
    850                 LOG(VB_FILE, LOG_DEBUG, LOC +
     858                LOG(VB_FILE, LOG_INFO, LOC +
    851859                    "Shrinking read, near end of buffer");
    852860            }
    853861
    void RingBuffer::run(void) 
    858866                    "Reading enough data to start playback");
    859867            }
    860868
    861             LOG(VB_FILE, LOG_DEBUG, LOC +
     869            LOG(VB_FILE, LOG_INFO, LOC +
    862870                QString("safe_read(...@%1, %2) -- begin")
    863871                    .arg(rbwpos).arg(totfree));
    864872
    void RingBuffer::run(void) 
    896904                        LOC + QString("rbwpos += %1K requested %2K in read")
    897905                        .arg(read_return/1024,3).arg(totfree/1024,3));
    898906                }
     907                else
     908                {
     909                    LOG(VB_FILE, LOG_INFO, LOC + "rbwpos != rbwposcopy");
     910                }
    899911                rbwlock.unlock();
    900912                poslock.unlock();
    901913            }
    902914        }
     915        else
     916        {
     917            LOG(VB_FILE, LOG_INFO, 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
    void RingBuffer::run(void) 
    945961            used = bufferSize - ReadBufFree();
    946962        }
    947963
    948         LOG(VB_FILE, LOG_DEBUG, LOC + "@ end of read ahead loop");
     964        LOG(VB_FILE, LOG_INFO, LOC + "@ end of read ahead loop");
    949965
    950966        if (!readsallowed || commserror || ateof || setswitchtonext ||
    951967            (wanttoread <= used && wanttoread > 0))
    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_INFO, LOC + QString("used = %1").arg(bufferSize - ReadBufFree()));
    10951111                LOG(VB_GENERAL, LOG_INFO, LOC + "Waited " +
    10961112                    QString("%1").arg((elapsed / 250) * 0.25f, 3, 'f', 1) +
    10971113                    " seconds for data \n\t\t\tto become available..." +
    1098                     QString(" %2 < %3") .arg(avail).arg(count));
     1114                    QString(" %2 < %3") .arg(avail).arg(count) + QString(" thread:%1").arg(QThread::currentThreadId()));
    10991115            }
    11001116
    11011117            if (elapsed > 16000)