1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Fixed a possible race condition in cDiseqc::Execute()

This commit is contained in:
Klaus Schmidinger 2011-05-22 10:51:03 +02:00
parent 7978112850
commit d7c07ecbfd
5 changed files with 35 additions and 26 deletions

View File

@ -2707,3 +2707,6 @@ Dirk Leber <dirk.leber@reel-multimedia.com>
same as the existing one same as the existing one
for reporting that TsGetPayload() gets called without checking whether there actually for reporting that TsGetPayload() gets called without checking whether there actually
is a payload in the given TS packet is a payload in the given TS packet
Marco Göbenich <mg@needful.de>
for reporting a problem with executing diseqc commands from different threads

View File

@ -6607,7 +6607,7 @@ Video Disk Recorder Revision History
- Avoiding an unecessary call to Recordings.ResetResume() (thanks to Reinhard - Avoiding an unecessary call to Recordings.ResetResume() (thanks to Reinhard
Nissl). Nissl).
2011-05-21: Version 1.7.19 2011-05-22: Version 1.7.19
- Fixed cString's operator=(const char *String) in case the given string is the - Fixed cString's operator=(const char *String) in case the given string is the
same as the existing one (thanks to Dirk Leber). same as the existing one (thanks to Dirk Leber).
@ -6621,3 +6621,6 @@ Video Disk Recorder Revision History
- The primary device is now only avoided for recording if it is an old SD full - The primary device is now only avoided for recording if it is an old SD full
featured card. This is done through the new function cDevice::AvoidRecording(). featured card. This is done through the new function cDevice::AvoidRecording().
- Subtitle PIDs are now also decrypted (thanks to Reinhard Nissl). - Subtitle PIDs are now also decrypted (thanks to Reinhard Nissl).
- Fixed a possible race condition in cDiseqc::Execute() (reported by Marco Göbenich).
The return value of cDiseqcs::Get() is now const, so plugin authors may need to
adjust their code if they use this function.

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: diseqc.c 2.3 2011/05/21 22:07:08 kls Exp $ * $Id: diseqc.c 2.4 2011/05/22 10:36:12 kls Exp $
*/ */
#include "diseqc.h" #include "diseqc.h"
@ -59,7 +59,7 @@ bool cDiseqc::Parse(const char *s)
polarization = char(toupper(polarization)); polarization = char(toupper(polarization));
if (polarization == 'V' || polarization == 'H' || polarization == 'L' || polarization == 'R') { if (polarization == 'V' || polarization == 'H' || polarization == 'L' || polarization == 'R') {
parsing = true; parsing = true;
char *CurrentAction = NULL; const char *CurrentAction = NULL;
while (Execute(&CurrentAction) != daNone) while (Execute(&CurrentAction) != daNone)
; ;
parsing = false; parsing = false;
@ -75,7 +75,7 @@ bool cDiseqc::Parse(const char *s)
return result; return result;
} }
char *cDiseqc::Wait(char *s) const char *cDiseqc::Wait(const char *s) const
{ {
char *p = NULL; char *p = NULL;
errno = 0; errno = 0;
@ -89,19 +89,22 @@ char *cDiseqc::Wait(char *s)
return NULL; 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) { if (e) {
numCodes = 0; int NumCodes = 0;
char *t = s; const char *t = s;
char *p = s; char *p;
while (t < e) { while (t < e) {
if (numCodes < MaxDiseqcCodes) { if (NumCodes < MaxDiseqcCodes) {
errno = 0; errno = 0;
int n = strtol(t, &p, 16); int n = strtol(t, &p, 16);
if (!errno && p != t && 0 <= n && n <= 255) { if (!errno && p != t && 0 <= n && n <= 255) {
codes[numCodes++] = uchar(n); if (parsing) {
codes[NumCodes++] = uchar(n);
numCodes = NumCodes;
}
t = skipspace(p); t = skipspace(p);
} }
else { else {
@ -121,7 +124,7 @@ char *cDiseqc::Codes(char *s)
return NULL; return NULL;
} }
cDiseqc::eDiseqcActions cDiseqc::Execute(char **CurrentAction) cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction) const
{ {
if (!*CurrentAction) if (!*CurrentAction)
*CurrentAction = commands; *CurrentAction = commands;
@ -146,10 +149,10 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(char **CurrentAction)
cDiseqcs Diseqcs; 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; int Devices = 0;
for (cDiseqc *p = First(); p; p = Next(p)) { for (const cDiseqc *p = First(); p; p = Next(p)) {
if (p->Devices()) { if (p->Devices()) {
Devices = p->Devices(); Devices = p->Devices();
continue; continue;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: diseqc.h 2.1 2010/02/06 15:14:42 kls Exp $ * $Id: diseqc.h 2.2 2011/05/22 10:35:38 kls Exp $
*/ */
#ifndef __DISEQC_H #ifndef __DISEQC_H
@ -33,15 +33,15 @@ private:
int lof; int lof;
char *commands; char *commands;
bool parsing; bool parsing;
uchar codes[MaxDiseqcCodes]; mutable uchar codes[MaxDiseqcCodes];
int numCodes; mutable int numCodes;
char *Wait(char *s); const char *Wait(const char *s) const;
char *Codes(char *s); const char *Codes(const char *s) const;
public: public:
cDiseqc(void); cDiseqc(void);
~cDiseqc(); ~cDiseqc();
bool Parse(const char *s); 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 // Parses the DiSEqC commands and returns the appropriate action code
// with every call. CurrentAction must be the address of a character pointer, // with every call. CurrentAction must be the address of a character pointer,
// which is initialized to NULL. This pointer is used internally while parsing // which is initialized to NULL. This pointer is used internally while parsing
@ -55,12 +55,12 @@ public:
char Polarization(void) const { return polarization; } char Polarization(void) const { return polarization; }
int Lof(void) const { return lof; } int Lof(void) const { return lof; }
const char *Commands(void) const { return commands; } 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> { class cDiseqcs : public cConfig<cDiseqc> {
public: 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; extern cDiseqcs Diseqcs;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbdevice.c 2.38 2010/05/01 09:47:13 kls Exp $ * $Id: dvbdevice.c 2.39 2011/05/22 10:34:49 kls Exp $
*/ */
#include "dvbdevice.h" #include "dvbdevice.h"
@ -392,11 +392,11 @@ bool cDvbTuner::SetFrontend(void)
if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) { if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) {
unsigned int frequency = channel.Frequency(); unsigned int frequency = channel.Frequency();
if (Setup.DiSEqC) { 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) {
if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) { if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
cDiseqc::eDiseqcActions da; 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) { switch (da) {
case cDiseqc::daNone: break; case cDiseqc::daNone: break;
case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break; case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
@ -407,7 +407,7 @@ bool cDvbTuner::SetFrontend(void)
case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break; case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
case cDiseqc::daCodes: { case cDiseqc::daCodes: {
int n = 0; int n = 0;
uchar *codes = diseqc->Codes(n); const uchar *codes = diseqc->Codes(n);
if (codes) { if (codes) {
struct dvb_diseqc_master_cmd cmd; struct dvb_diseqc_master_cmd cmd;
cmd.msg_len = min(n, int(sizeof(cmd.msg))); cmd.msg_len = min(n, int(sizeof(cmd.msg)));