summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS1
-rw-r--r--HISTORY2
-rw-r--r--dvbdevice.c43
3 files changed, 40 insertions, 6 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 89b61b99..4217e53a 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -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
diff --git a/HISTORY b/HISTORY
index 8413bddf..9aa6db33 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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).
diff --git a/dvbdevice.c b/dvbdevice.c
index 3f38a0a4..d71702cf 100644
--- a/dvbdevice.c
+++ b/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.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);
}
}