Skip to content

Commit

Permalink
Fixes #9959. This fixes a race deadlock in FileRingBuffer::safe_read(…
Browse files Browse the repository at this point in the history
…RemoteFile *rf... and also makes sure we don't update rbwpos with read_return if rbspos has changed since we read in the data.

The first problem was discovered & fixed by Lawrence Rust. I discovered & fixed the other related problem when reviewing his patch.
  • Loading branch information
daniel-kristjansson committed Aug 1, 2011
1 parent acb9402 commit 3733544
Showing 1 changed file with 23 additions and 15 deletions.
38 changes: 23 additions & 15 deletions mythtv/libs/libmythtv/ringbuffer.cpp
Expand Up @@ -830,32 +830,40 @@ void RingBuffer::run(void)
MythTimer sr_timer;
sr_timer.start();

read_return = safe_read(readAheadBuffer + rbwpos, totfree);
int rbwposcopy = rbwpos;

// FileRingBuffer::safe_read(RemoteFile*...) acquires poslock;
// so we need to unlock this here to preserve locking order.
rbwlock.unlock();

read_return = safe_read(readAheadBuffer + rbwposcopy, totfree);

int sr_elapsed = sr_timer.elapsed();
uint64_t bps = !sr_elapsed ? 1000000001 :
(uint64_t)(((double)read_return * 8000.0) /
(double)sr_elapsed);
LOG(VB_FILE, LOG_INFO, LOC +
QString("safe_read(...@%1, %2) -> %3, took %4 ms %5")
.arg(rbwpos).arg(totfree).arg(read_return)
.arg(rbwposcopy).arg(totfree).arg(read_return)
.arg(sr_elapsed)
.arg(QString("(%1Mbps)").arg((double)bps / 1000000.0)));
UpdateStorageRate(bps);
rbwlock.unlock();
}

if (read_return >= 0)
{
poslock.lockForWrite();
rbwlock.lockForWrite();
internalreadpos += read_return;
rbwpos = (rbwpos + read_return) % bufferSize;
LOG(VB_FILE, LOG_DEBUG,
LOC + QString("rbwpos += %1K requested %2K in read")
.arg(read_return/1024,3).arg(totfree/1024,3));
rbwlock.unlock();
poslock.unlock();
if (read_return >= 0)
{
poslock.lockForWrite();
rbwlock.lockForWrite();
if (rbwposcopy == rbwpos)
{
internalreadpos += read_return;
rbwpos = (rbwpos + read_return) % bufferSize;
LOG(VB_FILE, LOG_DEBUG,
LOC + QString("rbwpos += %1K requested %2K in read")
.arg(read_return/1024,3).arg(totfree/1024,3));
}
rbwlock.unlock();
poslock.unlock();
}
}

int used = bufferSize - ReadBufFree();
Expand Down

0 comments on commit 3733544

Please sign in to comment.