Ticket #9959: 9959-v2.patch

File 9959-v2.patch, 2.6 KB (added by danielk, 10 years ago)
  • mythtv/libs/libmythtv/ringbuffer.cpp

    diff --git a/mythtv/libs/libmythtv/ringbuffer.cpp b/mythtv/libs/libmythtv/ringbuffer.cpp
    index 4c5a587..077c347 100644
    a b void RingBuffer::run(void) 
    830830            MythTimer sr_timer;
    831831            sr_timer.start();
    832832
    833             read_return = safe_read(readAheadBuffer + rbwpos, totfree);
     833            // NB If an error is encountered in FileRingBuffer::safe_read()
     834            // then poslock is read locked prior to calling Seek().
     835            // However, we have rbwlock locked which violates the lock
     836            // heirarchy:
     837            //  rwlock->poslock->rbrlock->rbwlock
     838            // This can cause a client to deadlock, so release rbwlock.
     839
     840            int rbwposcopy = rbwpos;
     841            rbwlock.unlock();
     842
     843            read_return = safe_read(readAheadBuffer + rbwposcopy, totfree);
    834844
    835845            int sr_elapsed = sr_timer.elapsed();
    836846            uint64_t bps = !sr_elapsed ? 1000000001 :
    void RingBuffer::run(void) 
    838848                                      (double)sr_elapsed);
    839849            LOG(VB_FILE, LOG_INFO, LOC +
    840850                QString("safe_read(...@%1, %2) -> %3, took %4 ms %5")
    841                     .arg(rbwpos).arg(totfree).arg(read_return)
     851                    .arg(rbwposcopy).arg(totfree).arg(read_return)
    842852                    .arg(sr_elapsed)
    843853                    .arg(QString("(%1Mbps)").arg((double)bps / 1000000.0)));
    844854            UpdateStorageRate(bps);
    845             rbwlock.unlock();
    846         }
    847855
    848         if (read_return >= 0)
    849         {
    850             poslock.lockForWrite();
    851             rbwlock.lockForWrite();
    852             internalreadpos += read_return;
    853             rbwpos = (rbwpos + read_return) % bufferSize;
    854             LOG(VB_FILE, LOG_DEBUG,
    855                 LOC + QString("rbwpos += %1K requested %2K in read")
    856                     .arg(read_return/1024,3).arg(totfree/1024,3));
    857             rbwlock.unlock();
    858             poslock.unlock();
     856            if (read_return > 0)
     857            {
     858                poslock.lockForWrite();
     859                rbwlock.lockForWrite();
     860                if (rbwposcopy == rbwpos)
     861                {
     862                    internalreadpos += read_return;
     863                    rbwpos = (rbwpos + read_return) % bufferSize;
     864                    LOG(VB_FILE, LOG_DEBUG,
     865                        LOC + QString("rbwpos += %1K requested %2K in read")
     866                        .arg(read_return/1024,3).arg(totfree/1024,3));
     867                }
     868                rbwlock.unlock();
     869                poslock.unlock();
     870            }
    859871        }
    860872
    861873        int used = bufferSize - ReadBufFree();