Added more checks and polling when getting frontend events

This commit is contained in:
Klaus Schmidinger 2004-10-30 14:21:13 +02:00
parent 72bdd01b43
commit d5018de4fe
3 changed files with 40 additions and 6 deletions

View File

@ -258,6 +258,7 @@ Werner Fink <werner@suse.de>
AC3 replay
for changing thread handling to make it work with NPTL ("Native Posix Thread Library")
for suggesting to replace usleep() calls with a pthread_cond_timedwait() based wait
for suggesting to add more checks and polling when getting frontend events
Rolf Hakenes <hakenes@hippomi.de>
for providing 'libdtv' and adapting the EIT mechanisms to it

View File

@ -3081,3 +3081,5 @@ Video Disk Recorder Revision History
2004-10-30: Version 1.3.15
- Fixed some typos in the Makefile's 'font' target (thanks to Uwe Hanke).
- Added more checks and polling when getting frontend events (based on a patch
from Werner Fink).

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbdevice.c 1.100 2004/10/24 11:06:37 kls Exp $
* $Id: dvbdevice.c 1.101 2004/10/30 14:18:53 kls Exp $
*/
#include "dvbdevice.h"
@ -81,6 +81,7 @@ private:
cMutex mutex;
cCondVar locked;
cCondWait newSet;
bool GetFrontendEvent(dvb_frontend_event &Event, int TimeoutMs = 0);
bool SetFrontend(void);
virtual void Action(void);
public:
@ -144,6 +145,36 @@ bool cDvbTuner::Locked(int TimeoutMs)
return tunerStatus >= tsLocked;
}
bool cDvbTuner::GetFrontendEvent(dvb_frontend_event &Event, int TimeoutMs)
{
if (TimeoutMs) {
struct pollfd pfd;
pfd.fd = fd_frontend;
pfd.events = POLLIN | POLLPRI;
do {
int stat = poll(&pfd, 1, TimeoutMs);
if (stat == 1)
break;
if (stat < 0) {
if (errno == EINTR)
continue;
esyslog("ERROR: frontend %d poll failed: %m", cardIndex);
}
return false;
} while (0);
}
do {
int stat = ioctl(fd_frontend, FE_GET_EVENT, &Event);
if (stat == 0)
return true;
if (stat < 0) {
if (errno == EINTR)
continue;
}
} while (0);
return false;
}
static unsigned int FrequencyToHz(unsigned int f)
{
while (f && f < 1000000)
@ -260,18 +291,17 @@ bool cDvbTuner::SetFrontend(void)
void cDvbTuner::Action(void)
{
dvb_frontend_event event;
active = true;
while (active) {
Lock();
if (tunerStatus == tsSet) {
dvb_frontend_event event;
while (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0)
while (GetFrontendEvent(event))
; // discard stale events
tunerStatus = SetFrontend() ? tsTuned : tsIdle;
}
if (tunerStatus != tsIdle) {
dvb_frontend_event event;
while (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) {
while (GetFrontendEvent(event, 10)) {
if (event.status & FE_REINIT) {
tunerStatus = tsSet;
esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex);
@ -306,7 +336,8 @@ void cDvbTuner::Action(void)
}
Unlock();
// in the beginning we loop more often to let the CAM connection start up fast
newSet.Wait((tunerStatus == tsTuned || ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000);
if (tunerStatus != tsTuned)
newSet.Wait((ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000);
}
}