summaryrefslogtreecommitdiff
path: root/dvbdevice.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2004-10-30 14:21:13 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2004-10-30 14:21:13 +0200
commitd5018de4feeadc6e5184a1e1dd648f7126e3c0b3 (patch)
tree7819ddb83be7313d3a755c5860209fa82e86a287 /dvbdevice.c
parent72bdd01b4386a33177b5f872b3d3fc15606cd79e (diff)
downloadvdr-d5018de4feeadc6e5184a1e1dd648f7126e3c0b3.tar.gz
vdr-d5018de4feeadc6e5184a1e1dd648f7126e3c0b3.tar.bz2
Added more checks and polling when getting frontend events
Diffstat (limited to 'dvbdevice.c')
-rw-r--r--dvbdevice.c43
1 files changed, 37 insertions, 6 deletions
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);
}
}