diseqc errors

Message ID 4DD8E95D.3090201@tvdr.de
State New
Headers

Commit Message

Klaus Schmidinger May 22, 2011, 10:45 a.m. UTC
  On 05/22/11 00:35, Klaus Schmidinger wrote:
> On 21.05.2011 23:51, Marco Göbenich wrote:
>> Hi!
>>
>> No, checked against vanilla vdr-1.6-0, diseq.c and diseq.h are not modified.
>> I looked again in the logs and it seems that this happens when a epg scan is triggered, all entries seem to occur on times when there are free devices.
>
> Sounds like two threads are accessing a cDiseqc object at the same time.
>
> For a quick test, can you please try adding the following two lines:
>
>
> char *cDiseqc::Codes(char *s)
> {
> static cMutex Mutex; //ADD
> cMutexLock MutexLock(&Mutex); //ADD
> char *e = strchr(s, ']');

Looks like cDiseqc::Execute(), if called at the same time from
two different threads, modified the member variable 'numCodes'
in both calls and thus one of them ended up getting too high.

I have attached a patch that should fix this. It also makes
the whole thing more 'const'.

Please let me know if this works in your environment.

Klaus

>> Am 21.05.2011 16:26, schrieb Klaus Schmidinger:
>>> On 04/25/11 23:37, Marco Göbenich wrote:
>>>> Hi!
>>>>
>>>> Forgot to say that I'm using vdr-1.6 with TechniSat Gigaswitch 9/20.
>>>>
>>>> Regards
>>>>
>>>> Marco
>>>>
>>>> Am 25.04.2011 23:25, schrieb Marco Göbenich:
>>>>> Hi!
>>>>>
>>>>> I get the following errors:
>>>>>
>>>>> Apr 25 22:22:56 vdr10 vdr: [7893] ERROR: too many codes in code sequence '[E0 10 38 F0] W15 A W15 t'
>>>>> Apr 25 22:25:44 vdr10 vdr: [7890] ERROR: too many codes in code sequence '[E0 10 38 F6] W15 B W15 t'
>>>>> Apr 25 22:25:44 vdr10 vdr: [7893] ERROR: too many codes in code sequence '[E0 10 38 F6] W15 B W15 t'
>>>>> Apr 25 22:40:36 vdr10 vdr: [7896] ERROR: too many codes in code sequence '[E0 10 38 F5] W15 B W15 T'
>>>>> Apr 25 22:46:45 vdr10 vdr: [7890] ERROR: too many codes in code sequence '[E0 10 38 F6] W15 B W15 t'
>>>>> Apr 25 22:52:21 vdr10 vdr: [7893] ERROR: too many codes in code sequence '[E0 10 38 F3] W15 A W15 T'
>>>>> Apr 25 23:19:42 vdr10 vdr: [7893] ERROR: too many codes in code sequence '[E0 10 38 F7] W15 B W15 T'
>>>>>
>>>>> No Problems with recordings so far, but my diseqc.conf is from the wiki
>>>>> and I don't know how to solve this..
>>>>>
>>>>> my diseqc.conf:
>>>>> S19.2E 11700 V 9750 t v W15 [E0 10 38 F0] W15 A W15 t
>>>>> S19.2E 99999 V 10600 t v W15 [E0 10 38 F1] W15 A W15 T
>>>>> S19.2E 11700 H 9750 t V W15 [E0 10 38 F2] W15 A W15 t
>>>>> S19.2E 99999 H 10600 t V W15 [E0 10 38 F3] W15 A W15 T
>>>>>
>>>>> S13.0E 11700 V 9750 t v W15 [E0 10 38 F4] W15 B W15 t
>>>>> S13.0E 99999 V 10600 t v W15 [E0 10 38 F5] W15 B W15 T
>>>>> S13.0E 11700 H 9750 t V W15 [E0 10 38 F6] W15 B W15 t
>>>>> S13.0E 99999 H 10600 t V W15 [E0 10 38 F7] W15 B W15 T
>>> I can't see why this error would occur, your diseqc.conf looks fine.
>>>
>>> Is your diseqc.h or diseqc.c source file patched in any way?
>>>
>>> KlAUS
  

Comments

Marco Göbenich May 22, 2011, 11:21 a.m. UTC | #1
Hi!

Would there be a  patch for 1.6.0?

Regards

Marco


Am 22.05.2011 12:45, schrieb Klaus Schmidinger:
> On 05/22/11 00:35, Klaus Schmidinger wrote:
>> On 21.05.2011 23:51, Marco Göbenich wrote:
>>> Hi!
>>>
>>> No, checked against vanilla vdr-1.6-0, diseq.c and diseq.h are not modified.
>>> I looked again in the logs and it seems that this happens when a epg scan is triggered, all entries seem to occur on times when there are free devices.
>> Sounds like two threads are accessing a cDiseqc object at the same time.
>>
>> For a quick test, can you please try adding the following two lines:
>>
>>
>> char *cDiseqc::Codes(char *s)
>> {
>> static cMutex Mutex; //ADD
>> cMutexLock MutexLock(&Mutex); //ADD
>> char *e = strchr(s, ']');
> Looks like cDiseqc::Execute(), if called at the same time from
> two different threads, modified the member variable 'numCodes'
> in both calls and thus one of them ended up getting too high.
>
> I have attached a patch that should fix this. It also makes
> the whole thing more 'const'.
>
> Please let me know if this works in your environment.
>
> Klaus
>
>>> Am 21.05.2011 16:26, schrieb Klaus Schmidinger:
>>>> On 04/25/11 23:37, Marco Göbenich wrote:
>>>>> Hi!
>>>>>
>>>>> Forgot to say that I'm using vdr-1.6 with TechniSat Gigaswitch 9/20.
>>>>>
>>>>> Regards
>>>>>
>>>>> Marco
>>>>>
>>>>> Am 25.04.2011 23:25, schrieb Marco Göbenich:
>>>>>> Hi!
>>>>>>
>>>>>> I get the following errors:
>>>>>>
>>>>>> Apr 25 22:22:56 vdr10 vdr: [7893] ERROR: too many codes in code sequence '[E0 10 38 F0] W15 A W15 t'
>>>>>> Apr 25 22:25:44 vdr10 vdr: [7890] ERROR: too many codes in code sequence '[E0 10 38 F6] W15 B W15 t'
>>>>>> Apr 25 22:25:44 vdr10 vdr: [7893] ERROR: too many codes in code sequence '[E0 10 38 F6] W15 B W15 t'
>>>>>> Apr 25 22:40:36 vdr10 vdr: [7896] ERROR: too many codes in code sequence '[E0 10 38 F5] W15 B W15 T'
>>>>>> Apr 25 22:46:45 vdr10 vdr: [7890] ERROR: too many codes in code sequence '[E0 10 38 F6] W15 B W15 t'
>>>>>> Apr 25 22:52:21 vdr10 vdr: [7893] ERROR: too many codes in code sequence '[E0 10 38 F3] W15 A W15 T'
>>>>>> Apr 25 23:19:42 vdr10 vdr: [7893] ERROR: too many codes in code sequence '[E0 10 38 F7] W15 B W15 T'
>>>>>>
>>>>>> No Problems with recordings so far, but my diseqc.conf is from the wiki
>>>>>> and I don't know how to solve this..
>>>>>>
>>>>>> my diseqc.conf:
>>>>>> S19.2E 11700 V 9750 t v W15 [E0 10 38 F0] W15 A W15 t
>>>>>> S19.2E 99999 V 10600 t v W15 [E0 10 38 F1] W15 A W15 T
>>>>>> S19.2E 11700 H 9750 t V W15 [E0 10 38 F2] W15 A W15 t
>>>>>> S19.2E 99999 H 10600 t V W15 [E0 10 38 F3] W15 A W15 T
>>>>>>
>>>>>> S13.0E 11700 V 9750 t v W15 [E0 10 38 F4] W15 B W15 t
>>>>>> S13.0E 99999 V 10600 t v W15 [E0 10 38 F5] W15 B W15 T
>>>>>> S13.0E 11700 H 9750 t V W15 [E0 10 38 F6] W15 B W15 t
>>>>>> S13.0E 99999 H 10600 t V W15 [E0 10 38 F7] W15 B W15 T
>>>> I can't see why this error would occur, your diseqc.conf looks fine.
>>>>
>>>> Is your diseqc.h or diseqc.c source file patched in any way?
>>>>
>>>> KlAUS
>>>>
>>>>
>>>> _______________________________________________
>>>> vdr mailing list
>>>> vdr@linuxtv.org
>>>> http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
  
Marco Göbenich May 22, 2011, 11:21 a.m. UTC | #2
Hi!

Would there be a  patch for 1.6.0?

Regards

Marco


Am 22.05.2011 12:45, schrieb Klaus Schmidinger:
> On 05/22/11 00:35, Klaus Schmidinger wrote:
>> On 21.05.2011 23:51, Marco Göbenich wrote:
>>> Hi!
>>>
>>> No, checked against vanilla vdr-1.6-0, diseq.c and diseq.h are not modified.
>>> I looked again in the logs and it seems that this happens when a epg scan is triggered, all entries seem to occur on times when there are free devices.
>> Sounds like two threads are accessing a cDiseqc object at the same time.
>>
>> For a quick test, can you please try adding the following two lines:
>>
>>
>> char *cDiseqc::Codes(char *s)
>> {
>> static cMutex Mutex; //ADD
>> cMutexLock MutexLock(&Mutex); //ADD
>> char *e = strchr(s, ']');
> Looks like cDiseqc::Execute(), if called at the same time from
> two different threads, modified the member variable 'numCodes'
> in both calls and thus one of them ended up getting too high.
>
> I have attached a patch that should fix this. It also makes
> the whole thing more 'const'.
>
> Please let me know if this works in your environment.
>
> Klaus
>
>>> Am 21.05.2011 16:26, schrieb Klaus Schmidinger:
>>>> On 04/25/11 23:37, Marco Göbenich wrote:
>>>>> Hi!
>>>>>
>>>>> Forgot to say that I'm using vdr-1.6 with TechniSat Gigaswitch 9/20.
>>>>>
>>>>> Regards
>>>>>
>>>>> Marco
>>>>>
>>>>> Am 25.04.2011 23:25, schrieb Marco Göbenich:
>>>>>> Hi!
>>>>>>
>>>>>> I get the following errors:
>>>>>>
>>>>>> Apr 25 22:22:56 vdr10 vdr: [7893] ERROR: too many codes in code sequence '[E0 10 38 F0] W15 A W15 t'
>>>>>> Apr 25 22:25:44 vdr10 vdr: [7890] ERROR: too many codes in code sequence '[E0 10 38 F6] W15 B W15 t'
>>>>>> Apr 25 22:25:44 vdr10 vdr: [7893] ERROR: too many codes in code sequence '[E0 10 38 F6] W15 B W15 t'
>>>>>> Apr 25 22:40:36 vdr10 vdr: [7896] ERROR: too many codes in code sequence '[E0 10 38 F5] W15 B W15 T'
>>>>>> Apr 25 22:46:45 vdr10 vdr: [7890] ERROR: too many codes in code sequence '[E0 10 38 F6] W15 B W15 t'
>>>>>> Apr 25 22:52:21 vdr10 vdr: [7893] ERROR: too many codes in code sequence '[E0 10 38 F3] W15 A W15 T'
>>>>>> Apr 25 23:19:42 vdr10 vdr: [7893] ERROR: too many codes in code sequence '[E0 10 38 F7] W15 B W15 T'
>>>>>>
>>>>>> No Problems with recordings so far, but my diseqc.conf is from the wiki
>>>>>> and I don't know how to solve this..
>>>>>>
>>>>>> my diseqc.conf:
>>>>>> S19.2E 11700 V 9750 t v W15 [E0 10 38 F0] W15 A W15 t
>>>>>> S19.2E 99999 V 10600 t v W15 [E0 10 38 F1] W15 A W15 T
>>>>>> S19.2E 11700 H 9750 t V W15 [E0 10 38 F2] W15 A W15 t
>>>>>> S19.2E 99999 H 10600 t V W15 [E0 10 38 F3] W15 A W15 T
>>>>>>
>>>>>> S13.0E 11700 V 9750 t v W15 [E0 10 38 F4] W15 B W15 t
>>>>>> S13.0E 99999 V 10600 t v W15 [E0 10 38 F5] W15 B W15 T
>>>>>> S13.0E 11700 H 9750 t V W15 [E0 10 38 F6] W15 B W15 t
>>>>>> S13.0E 99999 H 10600 t V W15 [E0 10 38 F7] W15 B W15 T
>>>> I can't see why this error would occur, your diseqc.conf looks fine.
>>>>
>>>> Is your diseqc.h or diseqc.c source file patched in any way?
>>>>
>>>> KlAUS
>>>>
>>>>
>>>> _______________________________________________
>>>> vdr mailing list
>>>> vdr@linuxtv.org
>>>> http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
  

Patch

diff -u -b -r2.3 ./diseqc.c
--- ./diseqc.c	2011/05/21 22:07:08	2.3
+++ ./diseqc.c	2011/05/22 10:36:12
@@ -59,7 +59,7 @@ 
         polarization = char(toupper(polarization));
         if (polarization == 'V' || polarization == 'H' || polarization == 'L' || polarization == 'R') {
            parsing = true;
-           char *CurrentAction = NULL;
+           const char *CurrentAction = NULL;
            while (Execute(&CurrentAction) != daNone)
                  ;
            parsing = false;
@@ -75,7 +75,7 @@ 
   return result;
 }
 
-char *cDiseqc::Wait(char *s)
+const char *cDiseqc::Wait(const char *s) const
 {
   char *p = NULL;
   errno = 0;
@@ -89,19 +89,22 @@ 
   return NULL;
 }
 
-char *cDiseqc::Codes(char *s)
+const char *cDiseqc::Codes(const char *s) const
 {
-  char *e = strchr(s, ']');
+  const char *e = strchr(s, ']');
   if (e) {
-     numCodes = 0;
-     char *t = s;
-     char *p = s;
+     int NumCodes = 0;
+     const char *t = s;
+     char *p;
      while (t < e) {
-           if (numCodes < MaxDiseqcCodes) {
+           if (NumCodes < MaxDiseqcCodes) {
               errno = 0;
               int n = strtol(t, &p, 16);
               if (!errno && p != t && 0 <= n && n <= 255) {
-                 codes[numCodes++] = uchar(n);
+                 if (parsing) {
+                    codes[NumCodes++] = uchar(n);
+                    numCodes = NumCodes;
+                    }
                  t = skipspace(p);
                  }
               else {
@@ -121,7 +124,7 @@ 
   return NULL;
 }
 
-cDiseqc::eDiseqcActions cDiseqc::Execute(char **CurrentAction)
+cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction) const
 {
   if (!*CurrentAction)
      *CurrentAction = commands;
@@ -146,10 +149,10 @@ 
 
 cDiseqcs Diseqcs;
 
-cDiseqc *cDiseqcs::Get(int Device, int Source, int Frequency, char Polarization)
+const cDiseqc *cDiseqcs::Get(int Device, int Source, int Frequency, char Polarization) const
 {
   int Devices = 0;
-  for (cDiseqc *p = First(); p; p = Next(p)) {
+  for (const cDiseqc *p = First(); p; p = Next(p)) {
       if (p->Devices()) {
          Devices = p->Devices();
          continue;
diff -u -b -r2.1 ./diseqc.h
--- ./diseqc.h	2010/02/06 15:14:42	2.1
+++ ./diseqc.h	2011/05/22 10:35:38
@@ -33,15 +33,15 @@ 
   int lof;
   char *commands;
   bool parsing;
-  uchar codes[MaxDiseqcCodes];
-  int numCodes;
-  char *Wait(char *s);
-  char *Codes(char *s);
+  mutable uchar codes[MaxDiseqcCodes];
+  mutable int numCodes;
+  const char *Wait(const char *s) const;
+  const char *Codes(const char *s) const;
 public:
   cDiseqc(void);
   ~cDiseqc();
   bool Parse(const char *s);
-  eDiseqcActions Execute(char **CurrentAction);
+  eDiseqcActions Execute(const char **CurrentAction) const;
       // Parses the DiSEqC commands and returns the appropriate action code
       // with every call. CurrentAction must be the address of a character pointer,
       // which is initialized to NULL. This pointer is used internally while parsing
@@ -55,12 +55,12 @@ 
   char Polarization(void) const { return polarization; }
   int Lof(void) const { return lof; }
   const char *Commands(void) const { return commands; }
-  uchar *Codes(int &NumCodes) { NumCodes = numCodes; return numCodes ? codes : NULL; }
+  const uchar *Codes(int &NumCodes) const { NumCodes = numCodes; return numCodes ? codes : NULL; }
   };
 
 class cDiseqcs : public cConfig<cDiseqc> {
 public:
-  cDiseqc *Get(int Device, int Source, int Frequency, char Polarization);
+  const cDiseqc *Get(int Device, int Source, int Frequency, char Polarization) const;
   };
 
 extern cDiseqcs Diseqcs;
diff -u -b -r2.38 ./dvbdevice.c
--- ./dvbdevice.c	2010/05/01 09:47:13	2.38
+++ ./dvbdevice.c	2011/05/22 10:34:49
@@ -392,11 +392,11 @@ 
   if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) {
      unsigned int frequency = channel.Frequency();
      if (Setup.DiSEqC) {
-        cDiseqc *diseqc = Diseqcs.Get(device, channel.Source(), channel.Frequency(), dtp.Polarization());
+        const cDiseqc *diseqc = Diseqcs.Get(device, channel.Source(), channel.Frequency(), dtp.Polarization());
         if (diseqc) {
            if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
               cDiseqc::eDiseqcActions da;
-              for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) {
+              for (const char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) {
                   switch (da) {
                     case cDiseqc::daNone:      break;
                     case cDiseqc::daToneOff:   CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
@@ -407,7 +407,7 @@ 
                     case cDiseqc::daMiniB:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
                     case cDiseqc::daCodes: {
                          int n = 0;
-                         uchar *codes = diseqc->Codes(n);
+                         const uchar *codes = diseqc->Codes(n);
                          if (codes) {
                             struct dvb_diseqc_master_cmd cmd;
                             cmd.msg_len = min(n, int(sizeof(cmd.msg)));