mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Fixed cDvbTuner to avoid lockups on NPTL systems
This commit is contained in:
parent
9dd6796702
commit
7533b69e9b
@ -737,6 +737,7 @@ Marcel Wiesweg <marcel.wiesweg@gmx.de>
|
||||
for adding play mode pmVideoOnly
|
||||
for fixing a possible crash with inconsistent SI data
|
||||
for pointing out a problem with the cChannel copy constructor
|
||||
for fixing cDvbTuner to avoid lockups on NPTL systems
|
||||
|
||||
Torsten Herz <torsten.herz@web.de>
|
||||
for fixing a possible deadlock when using the "Blue" button in the "Schedules" menu
|
||||
|
1
HISTORY
1
HISTORY
@ -3710,3 +3710,4 @@ Video Disk Recorder Revision History
|
||||
available" happens if VDR is started with the current channel being an encrypted
|
||||
one, or a timer on such a channel hits right after starting VDR.
|
||||
- Fixed cVideoRepacker to better handle errors in data (thanks to Reinhard Nissl).
|
||||
- Fixed cDvbTuner to avoid lockups on NPTL systems (thanks to Marcel Wiesweg).
|
||||
|
65
dvbdevice.c
65
dvbdevice.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: dvbdevice.c 1.135 2005/08/20 15:22:36 kls Exp $
|
||||
* $Id: dvbdevice.c 1.136 2005/08/21 09:17:20 kls Exp $
|
||||
*/
|
||||
|
||||
#include "dvbdevice.h"
|
||||
@ -81,7 +81,7 @@ private:
|
||||
eTunerStatus tunerStatus;
|
||||
cMutex mutex;
|
||||
cCondVar locked;
|
||||
cCondWait newSet;
|
||||
cCondVar newSet;
|
||||
bool GetFrontendEvent(dvb_frontend_event &Event, int TimeoutMs = 0);
|
||||
bool SetFrontend(void);
|
||||
virtual void Action(void);
|
||||
@ -112,7 +112,8 @@ cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType, cCi
|
||||
cDvbTuner::~cDvbTuner()
|
||||
{
|
||||
tunerStatus = tsIdle;
|
||||
newSet.Signal();
|
||||
newSet.Broadcast();
|
||||
locked.Broadcast();
|
||||
Cancel(3);
|
||||
}
|
||||
|
||||
@ -123,7 +124,7 @@ bool cDvbTuner::IsTunedTo(const cChannel *Channel) const
|
||||
|
||||
void cDvbTuner::Set(const cChannel *Channel, bool Tune, bool UseCa)
|
||||
{
|
||||
Lock();
|
||||
cMutexLock MutexLock(&mutex);
|
||||
if (Tune)
|
||||
tunerStatus = tsSet;
|
||||
else if (tunerStatus == tsCam)
|
||||
@ -132,12 +133,15 @@ void cDvbTuner::Set(const cChannel *Channel, bool Tune, bool UseCa)
|
||||
if (Channel->Ca() && tunerStatus != tsCam)
|
||||
startTime = time(NULL);
|
||||
channel = *Channel;
|
||||
Unlock();
|
||||
newSet.Signal();
|
||||
newSet.Broadcast();
|
||||
}
|
||||
|
||||
bool cDvbTuner::Locked(int TimeoutMs)
|
||||
{
|
||||
bool isLocked = (tunerStatus >= tsLocked);
|
||||
if (isLocked || !TimeoutMs)
|
||||
return isLocked;
|
||||
|
||||
cMutexLock MutexLock(&mutex);
|
||||
if (TimeoutMs && tunerStatus < tsLocked)
|
||||
locked.TimedWait(mutex, TimeoutMs);
|
||||
@ -292,25 +296,33 @@ void cDvbTuner::Action(void)
|
||||
{
|
||||
dvb_frontend_event event;
|
||||
while (Running()) {
|
||||
Lock();
|
||||
if (tunerStatus == tsSet) {
|
||||
while (GetFrontendEvent(event))
|
||||
; // discard stale events
|
||||
tunerStatus = SetFrontend() ? tsTuned : tsIdle;
|
||||
}
|
||||
if (tunerStatus != tsIdle) {
|
||||
while (GetFrontendEvent(event, 10)) {
|
||||
if (event.status & FE_REINIT) {
|
||||
tunerStatus = tsSet;
|
||||
esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex);
|
||||
}
|
||||
if (event.status & FE_HAS_LOCK) {
|
||||
cMutexLock MutexLock(&mutex);
|
||||
tunerStatus = tsLocked;
|
||||
locked.Broadcast();
|
||||
}
|
||||
}
|
||||
}
|
||||
bool hasEvent = GetFrontendEvent(event, 1);
|
||||
|
||||
cMutexLock MutexLock(&mutex);
|
||||
switch (tunerStatus) {
|
||||
case tsIdle:
|
||||
break;
|
||||
case tsSet:
|
||||
if (hasEvent)
|
||||
continue;
|
||||
tunerStatus = SetFrontend() ? tsTuned : tsIdle;
|
||||
continue;
|
||||
case tsTuned:
|
||||
case tsLocked:
|
||||
case tsCam:
|
||||
if (hasEvent) {
|
||||
if (event.status & FE_REINIT) {
|
||||
tunerStatus = tsSet;
|
||||
esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex);
|
||||
}
|
||||
if (event.status & FE_HAS_LOCK) {
|
||||
tunerStatus = tsLocked;
|
||||
locked.Broadcast();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ciHandler) {
|
||||
if (ciHandler->Process() && useCa) {
|
||||
if (tunerStatus == tsLocked) {
|
||||
@ -332,10 +344,9 @@ void cDvbTuner::Action(void)
|
||||
else if (tunerStatus > tsLocked)
|
||||
tunerStatus = tsLocked;
|
||||
}
|
||||
Unlock();
|
||||
// in the beginning we loop more often to let the CAM connection start up fast
|
||||
if (tunerStatus != tsTuned)
|
||||
newSet.Wait((ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000);
|
||||
newSet.TimedWait(mutex, (ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user