Permalink
Browse files

Fixes #10541. Fix EIT scanning deadlock.

  • Loading branch information...
1 parent 406dcfa commit a1d9015924480bb8a733452e294fb72ebbfce94a @daniel-kristjansson daniel-kristjansson committed May 4, 2012
Showing with 44 additions and 8 deletions.
  1. +23 −4 mythtv/libs/libmythtv/eitscanner.cpp
  2. +5 −3 mythtv/libs/libmythtv/eitscanner.h
  3. +16 −1 mythtv/libs/libmythtv/tv_rec.cpp
@@ -75,7 +75,6 @@ void EITScanner::run(void)
static const float rt[] = { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, };
lock.lock();
- exitThread = false;
MythTimer t;
uint eitCount = 0;
@@ -149,9 +148,17 @@ void EITScanner::run(void)
}
lock.lock();
- if (!exitThread)
+ if ((activeScan || activeScanStopped) && !exitThread)
exitThreadCond.wait(&lock, 400); // sleep up to 400 ms.
+
+ if (!activeScan && !activeScanStopped)
+ {
+ activeScanStopped = true;
+ activeScanCond.wakeAll();
+ }
}
+ activeScanStopped = true;
+ activeScanCond.wakeAll();
lock.unlock();
}
@@ -271,13 +278,25 @@ void EITScanner::StartActiveScan(TVRec *_rec, uint max_seconds_per_source)
// Add a little randomness to trigger time so multiple
// cards will have a staggered channel changing time.
activeScanTrigTime += random() % 29;
+ activeScanStopped = false;
activeScan = true;
}
}
-void EITScanner::StopActiveScan()
+void EITScanner::StopActiveScan(void)
{
+ QMutexLocker locker(&lock);
+
+ activeScanStopped = false;
activeScan = false;
- rec = NULL;
+ exitThreadCond.wakeAll();
+
+ locker.unlock();
StopPassiveScan();
+ locker.relock();
+
+ while (!activeScan && !activeScanStopped)
+ activeScanCond.wait(&lock, 100);
+
+ rec = NULL;
}
@@ -54,11 +54,13 @@ class EITScanner : public QRunnable
EITHelper *eitHelper;
MThread *eventThread;
- bool exitThread;
- QWaitCondition exitThreadCond;
+ volatile bool exitThread;
+ QWaitCondition exitThreadCond; // protected by lock
TVRec *rec;
- bool activeScan;
+ volatile bool activeScan;
+ volatile bool activeScanStopped; // protected by lock
+ QWaitCondition activeScanCond; // protected by lock
QDateTime activeScanNextTrig;
uint activeScanTrigTime;
QStringList activeScanChannels;
@@ -3002,7 +3002,21 @@ QString TVRec::SetInput(QString input, uint requestType)
*/
void TVRec::SetChannel(QString name, uint requestType)
{
- QMutexLocker lock(&stateChangeLock);
+ 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();
+ }
+
LOG(VB_CHANNEL, LOG_INFO, LOC +
QString("SetChannel(%1) -- begin").arg(name));
@@ -3028,6 +3042,7 @@ void TVRec::SetChannel(QString name, uint requestType)
WaitForEventThreadSleep();
}
LOG(VB_CHANNEL, LOG_INFO, LOC + QString("SetChannel(%1) -- end").arg(name));
+ stateChangeLock.unlock();
}
void TVRec::GetNextProgram(BrowseDirection direction,

0 comments on commit a1d9015

Please sign in to comment.