diff --git a/mythtv/libs/libmythtv/ringbuffer.cpp b/mythtv/libs/libmythtv/ringbuffer.cpp
index 4c5a587..077c347 100644
a
|
b
|
void RingBuffer::run(void) |
830 | 830 | MythTimer sr_timer; |
831 | 831 | sr_timer.start(); |
832 | 832 | |
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); |
834 | 844 | |
835 | 845 | int sr_elapsed = sr_timer.elapsed(); |
836 | 846 | uint64_t bps = !sr_elapsed ? 1000000001 : |
… |
… |
void RingBuffer::run(void) |
838 | 848 | (double)sr_elapsed); |
839 | 849 | LOG(VB_FILE, LOG_INFO, LOC + |
840 | 850 | 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) |
842 | 852 | .arg(sr_elapsed) |
843 | 853 | .arg(QString("(%1Mbps)").arg((double)bps / 1000000.0))); |
844 | 854 | UpdateStorageRate(bps); |
845 | | rbwlock.unlock(); |
846 | | } |
847 | 855 | |
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 | } |
859 | 871 | } |
860 | 872 | |
861 | 873 | int used = bufferSize - ReadBufFree(); |