diff options
| -rw-r--r-- | CONTRIBUTORS | 1 | ||||
| -rw-r--r-- | HISTORY | 2 | ||||
| -rw-r--r-- | dvbdevice.c | 43 | 
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 @@ -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);          }  } | 
