Skip to content

Commit

Permalink
Fixes #10948. Fixes EIT shutdown deadlock.
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-kristjansson committed Jul 30, 2012
1 parent 94f1eff commit e8073bc
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 19 deletions.
10 changes: 6 additions & 4 deletions mythtv/libs/libmythtv/eitscanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,13 @@ void EITScanner::run(void)
if (!(*activeScanNextChan).isEmpty())
{
eitHelper->WriteEITCache();
rec->SetChannel(*activeScanNextChan, TVRec::kFlagEITScan);
LOG(VB_EIT, LOG_INFO,
LOC_ID + QString("Now looking for EIT data on "
"multiplex of channel %1")
if (rec->QueueEITChannelChange(*activeScanNextChan))
{
LOG(VB_EIT, LOG_INFO,
LOC_ID + QString("Now looking for EIT data on "
"multiplex of channel %1")
.arg(*activeScanNextChan));
}
}

activeScanNextTrig = MythDate::current()
Expand Down
55 changes: 40 additions & 15 deletions mythtv/libs/libmythtv/tv_rec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3039,20 +3039,7 @@ QString TVRec::SetInput(QString input, uint requestType)
*/
void TVRec::SetChannel(QString name, uint requestType)
{
if (TVRec::kFlagEITScan == requestType)
{
if (!stateChangeLock.tryLock())
{
LOG(VB_CHANNEL, LOG_INFO, LOC +
QString("SetChannel(%1, kFlagEITScan) -- "
"couldn't get lock aborting").arg(name));
return;
}
}
else
{
stateChangeLock.lock();
}
QMutexLocker locker(&stateChangeLock);

LOG(VB_CHANNEL, LOG_INFO, LOC +
QString("SetChannel(%1) -- begin").arg(name));
Expand All @@ -3067,6 +3054,16 @@ void TVRec::SetChannel(QString name, uint requestType)
// Clear the RingBuffer reset flag, in case we wait for a reset below
ClearFlags(kFlagRingBufferReady);

// Clear out any EITScan channel change requests
TuningQueue::iterator it = tuningRequests.begin();
while (it != tuningRequests.end())
{
if ((*it).flags & kFlagEITScan)
it = tuningRequests.erase(it);
else
++it;
}

// Actually add the tuning request to the queue, and
// then wait for it to start tuning
tuningRequests.enqueue(TuningRequest(requestType, name));
Expand All @@ -3079,7 +3076,35 @@ void TVRec::SetChannel(QString name, uint requestType)
WaitForEventThreadSleep();
}
LOG(VB_CHANNEL, LOG_INFO, LOC + QString("SetChannel(%1) -- end").arg(name));
stateChangeLock.unlock();
}

/** \brief Queues up a channel change for the EITScanner.
*
* Unlike the normal SetChannel() this does not block until
* the channel change occurs to avoid a deadlock if
* EITScanner::StopActiveScan() is called with the stateChangeLock
* held while the EITScanner is calling TVRec::SetChannel().
*/
bool TVRec::QueueEITChannelChange(const QString &name)
{
LOG(VB_CHANNEL, LOG_INFO, LOC +
QString("QueueEITChannelChange(%1) -- begin").arg(name));

bool ok = false;
if (stateChangeLock.tryLock())
{
if (tuningRequests.empty())
{
tuningRequests.enqueue(TuningRequest(kFlagEITScan, name));
ok = true;
}
stateChangeLock.unlock();
}

LOG(VB_CHANNEL, LOG_INFO, LOC +
QString("QueueEITChannelChange(%1) -- end --> %2").arg(name).arg(ok));

return ok;
}

void TVRec::GetNextProgram(BrowseDirection direction,
Expand Down
1 change: 1 addition & 0 deletions mythtv/libs/libmythtv/tv_rec.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ class MTV_PUBLIC TVRec : public SignalMonitorListener, public QRunnable
void ChangeChannel(ChannelChangeDirection dir)
{ SetChannel(QString("NextChannel %1").arg((int)dir)); }
void SetChannel(QString name, uint requestType = kFlagDetect);
bool QueueEITChannelChange(const QString &name);

int SetSignalMonitoringRate(int msec, int notifyFrontend = 1);
int GetPictureAttribute(PictureAttribute attr);
Expand Down

0 comments on commit e8073bc

Please sign in to comment.