Centralized 'thread active' handling

This commit is contained in:
Klaus Schmidinger 2005-08-13 13:17:24 +02:00
parent 1921c7465f
commit ccb0add798
18 changed files with 118 additions and 142 deletions

View File

@ -1417,3 +1417,6 @@ Frank Kr
Bernhard Stegmaier <bernhard.stegmaier@in.tum.de> Bernhard Stegmaier <bernhard.stegmaier@in.tum.de>
for reporting a problem in cEITScanner::Process() with forced EPG scans if EPG for reporting a problem in cEITScanner::Process() with forced EPG scans if EPG
scan timeout is set to 0 scan timeout is set to 0
Klaus ??? <klaus@reel-multimedia.com>
for reporting a race condition in cTransfer.

View File

@ -3671,3 +3671,12 @@ Video Disk Recorder Revision History
- Fixed setting system time to avoid time jumps in case of faulty data (thanks - Fixed setting system time to avoid time jumps in case of faulty data (thanks
to Andreas Böttger). to Andreas Böttger).
- Fixed a memory leak in the SVDRP command LSTE (thanks to Stefan Huelswitt). - Fixed a memory leak in the SVDRP command LSTE (thanks to Stefan Huelswitt).
2005-08-13: Version 1.3.29
- Fixed a race condition in cTransfer (thanks to Klaus ??? for reporting this one).
In doing so, the 'active' variables used by the actual derived cThread classes
have been replaced by the cThread::Active() function. The previous functionality
of cThread::Active() has been moved into the new cThread::Running().
Plugin authors may want to check their derived cThread classes and replace any 'active'
variables the same way as, for instance, done in transfer.c.

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: config.h 1.222 2005/07/30 09:19:25 kls Exp $ * $Id: config.h 1.223 2005/08/13 09:43:27 kls Exp $
*/ */
#ifndef __CONFIG_H #ifndef __CONFIG_H
@ -20,8 +20,8 @@
#include "i18n.h" #include "i18n.h"
#include "tools.h" #include "tools.h"
#define VDRVERSION "1.3.28" #define VDRVERSION "1.3.29"
#define VDRVERSNUM 10328 // Version * 10000 + Major * 100 + Minor #define VDRVERSNUM 10329 // Version * 10000 + Major * 100 + Minor
#define MAXPRIORITY 99 #define MAXPRIORITY 99
#define MAXLIFETIME 99 #define MAXLIFETIME 99

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: cutter.c 1.8 2005/05/15 14:21:08 kls Exp $ * $Id: cutter.c 1.9 2005/08/13 11:49:02 kls Exp $
*/ */
#include "cutter.h" #include "cutter.h"
@ -18,7 +18,6 @@
class cCuttingThread : public cThread { class cCuttingThread : public cThread {
private: private:
const char *error; const char *error;
bool active;
int fromFile, toFile; int fromFile, toFile;
cFileName *fromFileName, *toFileName; cFileName *fromFileName, *toFileName;
cIndexFile *fromIndex, *toIndex; cIndexFile *fromIndex, *toIndex;
@ -35,7 +34,6 @@ cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName)
:cThread("video cutting") :cThread("video cutting")
{ {
error = NULL; error = NULL;
active = false;
fromFile = toFile = -1; fromFile = toFile = -1;
fromFileName = toFileName = NULL; fromFileName = toFileName = NULL;
fromIndex = toIndex = NULL; fromIndex = toIndex = NULL;
@ -53,7 +51,6 @@ cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName)
cCuttingThread::~cCuttingThread() cCuttingThread::~cCuttingThread()
{ {
active = false;
Cancel(3); Cancel(3);
delete fromFileName; delete fromFileName;
delete toFileName; delete toFileName;
@ -67,7 +64,8 @@ void cCuttingThread::Action(void)
if (Mark) { if (Mark) {
fromFile = fromFileName->Open(); fromFile = fromFileName->Open();
toFile = toFileName->Open(); toFile = toFileName->Open();
active = fromFile >= 0 && toFile >= 0; if (fromFile < 0 || toFile < 0)
return;
int Index = Mark->position; int Index = Mark->position;
Mark = fromMarks.Next(Mark); Mark = fromMarks.Next(Mark);
int FileSize = 0; int FileSize = 0;
@ -78,7 +76,7 @@ void cCuttingThread::Action(void)
uchar buffer[MAXFRAMESIZE]; uchar buffer[MAXFRAMESIZE];
bool LastMark = false; bool LastMark = false;
bool cutIn = true; bool cutIn = true;
while (active) { while (Active()) {
uchar FileNumber; uchar FileNumber;
int FileOffset, Length; int FileOffset, Length;
uchar PictureType; uchar PictureType;
@ -215,7 +213,7 @@ bool cCutter::Start(const char *FileName)
void cCutter::Stop(void) void cCutter::Stop(void)
{ {
bool Interrupted = cuttingThread && cuttingThread->Active(); bool Interrupted = cuttingThread && cuttingThread->Running();
const char *Error = cuttingThread ? cuttingThread->Error() : NULL; const char *Error = cuttingThread ? cuttingThread->Error() : NULL;
delete cuttingThread; delete cuttingThread;
cuttingThread = NULL; cuttingThread = NULL;
@ -232,7 +230,7 @@ void cCutter::Stop(void)
bool cCutter::Active(void) bool cCutter::Active(void)
{ {
if (cuttingThread) { if (cuttingThread) {
if (cuttingThread->Active()) if (cuttingThread->Running())
return true; return true;
error = cuttingThread->Error(); error = cuttingThread->Error();
Stop(); Stop();

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: device.c 1.103 2005/06/12 13:39:11 kls Exp $ * $Id: device.c 1.104 2005/08/13 11:44:06 kls Exp $
*/ */
#include "device.h" #include "device.h"
@ -156,8 +156,6 @@ cDevice::cDevice(void)
SetVideoFormat(Setup.VideoFormat); SetVideoFormat(Setup.VideoFormat);
active = false;
mute = false; mute = false;
volume = Setup.CurrentVolume; volume = Setup.CurrentVolume;
@ -1126,25 +1124,25 @@ bool cDevice::Receiving(bool CheckAny) const
void cDevice::Action(void) void cDevice::Action(void)
{ {
if (active && OpenDvr()) { if (Active() && OpenDvr()) {
for (; active;) { while (Active()) {
// Read data from the DVR device: // Read data from the DVR device:
uchar *b = NULL; uchar *b = NULL;
if (GetTSPacket(b)) { if (GetTSPacket(b)) {
if (b) { if (b) {
int Pid = (((uint16_t)b[1] & PID_MASK_HI) << 8) | b[2]; int Pid = (((uint16_t)b[1] & PID_MASK_HI) << 8) | b[2];
// Distribute the packet to all attached receivers: // Distribute the packet to all attached receivers:
Lock(); Lock();
for (int i = 0; i < MAXRECEIVERS; i++) { for (int i = 0; i < MAXRECEIVERS; i++) {
if (receiver[i] && receiver[i]->WantsPid(Pid)) if (receiver[i] && receiver[i]->WantsPid(Pid))
receiver[i]->Receive(b, TS_SIZE); receiver[i]->Receive(b, TS_SIZE);
} }
Unlock(); Unlock();
} }
} }
else else
break; break;
} }
CloseDvr(); CloseDvr();
} }
} }
@ -1188,10 +1186,8 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
Receiver->device = this; Receiver->device = this;
receiver[i] = Receiver; receiver[i] = Receiver;
Unlock(); Unlock();
if (!active) { if (!Active())
active = true;
Start(); Start();
}
return true; return true;
} }
} }
@ -1218,10 +1214,8 @@ void cDevice::Detach(cReceiver *Receiver)
else if (receiver[i]) else if (receiver[i])
receiversLeft = true; receiversLeft = true;
} }
if (!receiversLeft) { if (!receiversLeft)
active = false;
Cancel(3); Cancel(3);
}
} }
void cDevice::DetachAll(int Pid) void cDevice::DetachAll(int Pid)
@ -1246,13 +1240,11 @@ cTSBuffer::cTSBuffer(int File, int Size, int CardIndex)
delivered = false; delivered = false;
ringBuffer = new cRingBufferLinear(Size, TS_SIZE, true, "TS"); ringBuffer = new cRingBufferLinear(Size, TS_SIZE, true, "TS");
ringBuffer->SetTimeouts(100, 100); ringBuffer->SetTimeouts(100, 100);
active = true;
Start(); Start();
} }
cTSBuffer::~cTSBuffer() cTSBuffer::~cTSBuffer()
{ {
active = false;
Cancel(3); Cancel(3);
delete ringBuffer; delete ringBuffer;
} }
@ -1262,20 +1254,20 @@ void cTSBuffer::Action(void)
if (ringBuffer) { if (ringBuffer) {
bool firstRead = true; bool firstRead = true;
cPoller Poller(f); cPoller Poller(f);
for (; active;) { while (Active()) {
if (firstRead || Poller.Poll(100)) { if (firstRead || Poller.Poll(100)) {
firstRead = false; firstRead = false;
int r = ringBuffer->Read(f); int r = ringBuffer->Read(f);
if (r < 0 && FATALERRNO) { if (r < 0 && FATALERRNO) {
if (errno == EOVERFLOW) if (errno == EOVERFLOW)
esyslog("ERROR: driver buffer overflow on device %d", cardIndex); esyslog("ERROR: driver buffer overflow on device %d", cardIndex);
else { else {
LOG_ERROR; LOG_ERROR;
break; break;
} }
} }
} }
} }
} }
} }

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: device.h 1.60 2005/07/30 09:31:53 kls Exp $ * $Id: device.h 1.61 2005/08/13 11:44:13 kls Exp $
*/ */
#ifndef __DEVICE_H #ifndef __DEVICE_H
@ -233,7 +233,6 @@ public:
// PID handle facilities // PID handle facilities
private: private:
bool active;
virtual void Action(void); virtual void Action(void);
protected: protected:
enum ePidType { ptAudio, ptVideo, ptPcr, ptTeletext, ptDolby, ptOther }; enum ePidType { ptAudio, ptVideo, ptPcr, ptTeletext, ptDolby, ptOther };
@ -518,7 +517,6 @@ class cTSBuffer : public cThread {
private: private:
int f; int f;
int cardIndex; int cardIndex;
bool active;
bool delivered; bool delivered;
cRingBufferLinear *ringBuffer; cRingBufferLinear *ringBuffer;
virtual void Action(void); virtual void Action(void);

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 1.131 2005/06/19 11:00:43 kls Exp $ * $Id: dvbdevice.c 1.132 2005/08/13 11:40:46 kls Exp $
*/ */
#include "dvbdevice.h" #include "dvbdevice.h"
@ -76,7 +76,6 @@ private:
cCiHandler *ciHandler; cCiHandler *ciHandler;
cChannel channel; cChannel channel;
const char *diseqcCommands; const char *diseqcCommands;
bool active;
bool useCa; bool useCa;
time_t startTime; time_t startTime;
eTunerStatus tunerStatus; eTunerStatus tunerStatus;
@ -101,7 +100,6 @@ cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType, cCi
frontendType = FrontendType; frontendType = FrontendType;
ciHandler = CiHandler; ciHandler = CiHandler;
diseqcCommands = NULL; diseqcCommands = NULL;
active = false;
useCa = false; useCa = false;
tunerStatus = tsIdle; tunerStatus = tsIdle;
startTime = time(NULL); startTime = time(NULL);
@ -113,7 +111,6 @@ cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType, cCi
cDvbTuner::~cDvbTuner() cDvbTuner::~cDvbTuner()
{ {
active = false;
tunerStatus = tsIdle; tunerStatus = tsIdle;
newSet.Signal(); newSet.Signal();
Cancel(3); Cancel(3);
@ -294,8 +291,7 @@ bool cDvbTuner::SetFrontend(void)
void cDvbTuner::Action(void) void cDvbTuner::Action(void)
{ {
dvb_frontend_event event; dvb_frontend_event event;
active = true; while (Active()) {
while (active) {
Lock(); Lock();
if (tunerStatus == tsSet) { if (tunerStatus == tsSet) {
while (GetFrontendEvent(event)) while (GetFrontendEvent(event))

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: dvbplayer.c 1.36 2005/07/30 10:00:24 kls Exp $ * $Id: dvbplayer.c 1.37 2005/08/13 12:27:17 kls Exp $
*/ */
#include "dvbplayer.h" #include "dvbplayer.h"
@ -79,7 +79,6 @@ private:
int wanted; int wanted;
int length; int length;
bool hasData; bool hasData;
bool active;
cCondWait newSet; cCondWait newSet;
protected: protected:
void Action(void); void Action(void);
@ -98,13 +97,11 @@ cNonBlockingFileReader::cNonBlockingFileReader(void)
buffer = NULL; buffer = NULL;
wanted = length = 0; wanted = length = 0;
hasData = false; hasData = false;
active = false;
Start(); Start();
} }
cNonBlockingFileReader::~cNonBlockingFileReader() cNonBlockingFileReader::~cNonBlockingFileReader()
{ {
active = false;
newSet.Signal(); newSet.Signal();
Cancel(3); Cancel(3);
free(buffer); free(buffer);
@ -147,8 +144,7 @@ int cNonBlockingFileReader::Read(int FileHandle, uchar *Buffer, int Length)
void cNonBlockingFileReader::Action(void) void cNonBlockingFileReader::Action(void)
{ {
active = true; while (Active()) {
while (active) {
Lock(); Lock();
if (!hasData && f >= 0 && buffer) { if (!hasData && f >= 0 && buffer) {
int r = safe_read(f, buffer + length, wanted - length); int r = safe_read(f, buffer + length, wanted - length);
@ -187,8 +183,6 @@ private:
cIndexFile *index; cIndexFile *index;
int replayFile; int replayFile;
bool eof; bool eof;
bool active;
bool running;
bool firstPacket; bool firstPacket;
ePlayModes playMode; ePlayModes playMode;
ePlayDirs playDir; ePlayDirs playDir;
@ -207,7 +201,7 @@ protected:
public: public:
cDvbPlayer(const char *FileName); cDvbPlayer(const char *FileName);
virtual ~cDvbPlayer(); virtual ~cDvbPlayer();
bool Active(void) { return active; } bool Active(void) { return cThread::Active(); }
void Pause(void); void Pause(void);
void Play(void); void Play(void);
void Forward(void); void Forward(void);
@ -233,8 +227,6 @@ cDvbPlayer::cDvbPlayer(const char *FileName)
backTrace = NULL; backTrace = NULL;
index = NULL; index = NULL;
eof = false; eof = false;
active = true;
running = false;
firstPacket = true; firstPacket = true;
playMode = pmPlay; playMode = pmPlay;
playDir = pdForward; playDir = pdForward;
@ -353,11 +345,8 @@ void cDvbPlayer::Activate(bool On)
if (replayFile >= 0) if (replayFile >= 0)
Start(); Start();
} }
else if (active) { else
running = false;
Cancel(9); Cancel(9);
active = false;
}
} }
void cDvbPlayer::Action(void) void cDvbPlayer::Action(void)
@ -374,8 +363,7 @@ void cDvbPlayer::Action(void)
int Length = 0; int Length = 0;
bool Sleep = false; bool Sleep = false;
running = true; while (Active() && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) {
while (running && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) {
if (Sleep) { if (Sleep) {
cCondWait::SleepMs(3); // this keeps the CPU load low cCondWait::SleepMs(3); // this keeps the CPU load low
Sleep = false; Sleep = false;
@ -501,7 +489,6 @@ void cDvbPlayer::Action(void)
Sleep = true; Sleep = true;
} }
} }
active = running = false;
cNonBlockingFileReader *nbfr = nonBlockingFileReader; cNonBlockingFileReader *nbfr = nonBlockingFileReader;
nonBlockingFileReader = NULL; nonBlockingFileReader = NULL;

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: recorder.c 1.13 2005/01/16 12:53:17 kls Exp $ * $Id: recorder.c 1.14 2005/08/13 11:33:35 kls Exp $
*/ */
#include <stdarg.h> #include <stdarg.h>
@ -29,7 +29,6 @@ private:
uchar pictureType; uchar pictureType;
int fileSize; int fileSize;
int recordFile; int recordFile;
bool active;
time_t lastDiskSpaceCheck; time_t lastDiskSpaceCheck;
bool RunningLowOnDiskSpace(void); bool RunningLowOnDiskSpace(void);
bool NextFile(void); bool NextFile(void);
@ -43,7 +42,6 @@ public:
cFileWriter::cFileWriter(const char *FileName, cRemux *Remux) cFileWriter::cFileWriter(const char *FileName, cRemux *Remux)
:cThread("file writer") :cThread("file writer")
{ {
active = false;
fileName = NULL; fileName = NULL;
remux = Remux; remux = Remux;
index = NULL; index = NULL;
@ -63,7 +61,6 @@ cFileWriter::cFileWriter(const char *FileName, cRemux *Remux)
cFileWriter::~cFileWriter() cFileWriter::~cFileWriter()
{ {
active = false;
Cancel(3); Cancel(3);
delete index; delete index;
delete fileName; delete fileName;
@ -96,13 +93,11 @@ bool cFileWriter::NextFile(void)
void cFileWriter::Action(void) void cFileWriter::Action(void)
{ {
time_t t = time(NULL); time_t t = time(NULL);
active = true; while (Active()) {
while (active) {
int Count; int Count;
uchar *p = remux->Get(Count, &pictureType); uchar *p = remux->Get(Count, &pictureType);
if (p) { if (p) {
//XXX+ active??? see old version (Busy) if (!Active() && pictureType == I_FRAME) // finish the recording before the next 'I' frame
if (!active && pictureType == I_FRAME) // finish the recording before the next 'I' frame
break; break;
if (NextFile()) { if (NextFile()) {
if (index && pictureType != NO_PICTURE) if (index && pictureType != NO_PICTURE)
@ -124,15 +119,12 @@ void cFileWriter::Action(void)
t = time(NULL); t = time(NULL);
} }
} }
active = false;
} }
cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids) cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids)
:cReceiver(Ca, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids) :cReceiver(Ca, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids)
,cThread("recording") ,cThread("recording")
{ {
active = false;
// Make sure the disk is up and running: // Make sure the disk is up and running:
SpinUpDisk(FileName); SpinUpDisk(FileName);
@ -157,25 +149,22 @@ void cRecorder::Activate(bool On)
writer->Start(); writer->Start();
Start(); Start();
} }
else if (active) { else
active = false;
Cancel(3); Cancel(3);
}
} }
void cRecorder::Receive(uchar *Data, int Length) void cRecorder::Receive(uchar *Data, int Length)
{ {
if (active) { if (Active()) {
int p = ringBuffer->Put(Data, Length); int p = ringBuffer->Put(Data, Length);
if (p != Length && active) if (p != Length && Active())
ringBuffer->ReportOverflow(Length - p); ringBuffer->ReportOverflow(Length - p);
} }
} }
void cRecorder::Action(void) void cRecorder::Action(void)
{ {
active = true; while (Active()) {
while (active) {
int r; int r;
uchar *b = ringBuffer->Get(r); uchar *b = ringBuffer->Get(r);
if (b) { if (b) {

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: recorder.h 1.3 2005/01/16 12:05:13 kls Exp $ * $Id: recorder.h 1.4 2005/08/13 11:31:18 kls Exp $
*/ */
#ifndef __RECORDER_H #ifndef __RECORDER_H
@ -23,7 +23,6 @@ private:
cRingBufferLinear *ringBuffer; cRingBufferLinear *ringBuffer;
cRemux *remux; cRemux *remux;
cFileWriter *writer; cFileWriter *writer;
bool active;
protected: protected:
virtual void Activate(bool On); virtual void Activate(bool On);
virtual void Receive(uchar *Data, int Length); virtual void Receive(uchar *Data, int Length);

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: remote.c 1.42 2005/03/20 13:25:31 kls Exp $ * $Id: remote.c 1.43 2005/08/13 11:28:35 kls Exp $
*/ */
#include "remote.h" #include "remote.h"
@ -213,7 +213,6 @@ cKbdRemote::cKbdRemote(void)
:cRemote("KBD") :cRemote("KBD")
,cThread("KBD remote control") ,cThread("KBD remote control")
{ {
active = false;
tcgetattr(STDIN_FILENO, &savedTm); tcgetattr(STDIN_FILENO, &savedTm);
struct termios tm; struct termios tm;
if (tcgetattr(STDIN_FILENO, &tm) == 0) { if (tcgetattr(STDIN_FILENO, &tm) == 0) {
@ -230,7 +229,6 @@ cKbdRemote::cKbdRemote(void)
cKbdRemote::~cKbdRemote() cKbdRemote::~cKbdRemote()
{ {
kbdAvailable = false; kbdAvailable = false;
active = false;
Cancel(3); Cancel(3);
tcsetattr(STDIN_FILENO, TCSANOW, &savedTm); tcsetattr(STDIN_FILENO, TCSANOW, &savedTm);
} }
@ -261,12 +259,11 @@ int cKbdRemote::MapCodeToFunc(uint64 Code)
void cKbdRemote::Action(void) void cKbdRemote::Action(void)
{ {
cPoller Poller(STDIN_FILENO); cPoller Poller(STDIN_FILENO);
active = true; while (Active()) {
while (active) {
if (Poller.Poll(100)) { if (Poller.Poll(100)) {
uint64 Command = 0; uint64 Command = 0;
uint i = 0; uint i = 0;
while (active && i < sizeof(Command)) { while (Active() && i < sizeof(Command)) {
uchar ch; uchar ch;
int r = read(STDIN_FILENO, &ch, 1); int r = read(STDIN_FILENO, &ch, 1);
if (r == 1) { if (r == 1) {

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: remote.h 1.29 2004/05/28 14:14:02 kls Exp $ * $Id: remote.h 1.30 2005/08/13 11:28:10 kls Exp $
*/ */
#ifndef __REMOTE_H #ifndef __REMOTE_H
@ -81,7 +81,6 @@ enum eKbdFunc {
class cKbdRemote : public cRemote, private cThread { class cKbdRemote : public cRemote, private cThread {
private: private:
bool active;
static bool kbdAvailable; static bool kbdAvailable;
static bool rawMode; static bool rawMode;
struct termios savedTm; struct termios savedTm;

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: sections.c 1.11 2005/05/29 11:43:17 kls Exp $ * $Id: sections.c 1.12 2005/08/13 11:25:04 kls Exp $
*/ */
#include "sections.h" #include "sections.h"
@ -44,7 +44,6 @@ cSectionHandler::cSectionHandler(cDevice *Device)
{ {
shp = new cSectionHandlerPrivate; shp = new cSectionHandlerPrivate;
device = Device; device = Device;
active = false;
statusCount = 0; statusCount = 0;
on = false; on = false;
waitForLock = false; waitForLock = false;
@ -54,7 +53,6 @@ cSectionHandler::cSectionHandler(cDevice *Device)
cSectionHandler::~cSectionHandler() cSectionHandler::~cSectionHandler()
{ {
active = false;
Cancel(3); Cancel(3);
cFilter *fi; cFilter *fi;
while ((fi = filters.First()) != NULL) while ((fi = filters.First()) != NULL)
@ -166,9 +164,8 @@ void cSectionHandler::SetStatus(bool On)
void cSectionHandler::Action(void) void cSectionHandler::Action(void)
{ {
active = true;
SetPriority(19); SetPriority(19);
while (active) { while (Active()) {
Lock(); Lock();
if (waitForLock) if (waitForLock)

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: sections.h 1.4 2004/08/08 13:44:17 kls Exp $ * $Id: sections.h 1.5 2005/08/13 11:23:55 kls Exp $
*/ */
#ifndef __SECTIONS_H #ifndef __SECTIONS_H
@ -25,7 +25,6 @@ class cSectionHandler : public cThread {
private: private:
cSectionHandlerPrivate *shp; cSectionHandlerPrivate *shp;
cDevice *device; cDevice *device;
bool active;
int statusCount; int statusCount;
bool on, waitForLock; bool on, waitForLock;
time_t lastIncompleteSection; time_t lastIncompleteSection;

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: thread.c 1.43 2005/05/29 11:40:30 kls Exp $ * $Id: thread.c 1.44 2005/08/13 11:22:37 kls Exp $
*/ */
#include "thread.h" #include "thread.h"
@ -197,7 +197,7 @@ bool cThread::emergencyExitRequested = false;
cThread::cThread(const char *Description) cThread::cThread(const char *Description)
{ {
running = false; running = active = false;
childTid = 0; childTid = 0;
description = NULL; description = NULL;
SetDescription(Description); SetDescription(Description);
@ -205,6 +205,7 @@ cThread::cThread(const char *Description)
cThread::~cThread() cThread::~cThread()
{ {
Cancel(); // just in case the derived class didn't call it
free(description); free(description);
} }
@ -233,6 +234,7 @@ void *cThread::StartThread(cThread *Thread)
Thread->Action(); Thread->Action();
if (Thread->description) if (Thread->description)
dsyslog("%s thread ended (pid=%d, tid=%ld)", Thread->description, getpid(), pthread_self()); dsyslog("%s thread ended (pid=%d, tid=%ld)", Thread->description, getpid(), pthread_self());
Thread->active = false;
Thread->running = false; Thread->running = false;
return NULL; return NULL;
} }
@ -240,21 +242,21 @@ void *cThread::StartThread(cThread *Thread)
bool cThread::Start(void) bool cThread::Start(void)
{ {
if (!running) { if (!running) {
running = true; running = active = true;
if (pthread_create(&childTid, NULL, (void *(*) (void *))&StartThread, (void *)this) == 0) { if (pthread_create(&childTid, NULL, (void *(*) (void *))&StartThread, (void *)this) == 0) {
pthread_detach(childTid); // auto-reap pthread_detach(childTid); // auto-reap
pthread_setschedparam(childTid, SCHED_RR, 0); pthread_setschedparam(childTid, SCHED_RR, 0);
} }
else { else {
LOG_ERROR; LOG_ERROR;
running = false; running = active = false;
return false; return false;
} }
} }
return true; return true;
} }
bool cThread::Active(void) bool cThread::Running(void)
{ {
if (running) { if (running) {
// //
@ -271,7 +273,7 @@ bool cThread::Active(void)
if (err != ESRCH) if (err != ESRCH)
LOG_ERROR; LOG_ERROR;
childTid = 0; childTid = 0;
running = false; running = active = false;
} }
else else
return true; return true;
@ -281,10 +283,11 @@ bool cThread::Active(void)
void cThread::Cancel(int WaitSeconds) void cThread::Cancel(int WaitSeconds)
{ {
active = false;
if (running) { if (running) {
if (WaitSeconds > 0) { if (WaitSeconds > 0) {
for (time_t t0 = time(NULL) + WaitSeconds; time(NULL) < t0; ) { for (time_t t0 = time(NULL) + WaitSeconds; time(NULL) < t0; ) {
if (!Active()) if (!Running())
return; return;
cCondWait::SleepMs(10); cCondWait::SleepMs(10);
} }

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: thread.h 1.28 2005/05/29 11:31:24 kls Exp $ * $Id: thread.h 1.29 2005/08/13 13:01:33 kls Exp $
*/ */
#ifndef __THREAD_H #ifndef __THREAD_H
@ -76,6 +76,7 @@ class cThread {
friend class cThreadLock; friend class cThreadLock;
private: private:
bool running; bool running;
bool active;
pthread_t childTid; pthread_t childTid;
cMutex mutex; cMutex mutex;
char *description; char *description;
@ -86,13 +87,30 @@ protected:
void Lock(void) { mutex.Lock(); } void Lock(void) { mutex.Lock(); }
void Unlock(void) { mutex.Unlock(); } void Unlock(void) { mutex.Unlock(); }
virtual void Action(void) = 0; virtual void Action(void) = 0;
///< A derived cThread class must implement the code it wants to
///< execute as a separate thread in this function. If this is
///< a loop, it must check Active() repeatedly to see whether
///< it's time to stop.
bool Active(void) { return active; }
///< Returns false if a derived cThread object shall leave its Action()
///< function.
void Cancel(int WaitSeconds = 0); void Cancel(int WaitSeconds = 0);
///< Cancels the thread by first setting 'active' to false, so that
///< the Action() loop can finish in an orderly fashion and then waiting
///< up to WaitSeconds seconds for the thread to actually end. If the
///< thread doesn't end by itself, it is killed.
public: public:
cThread(const char *Description = NULL); cThread(const char *Description = NULL);
///< Creates a new thread.
///< If Description is present, a log file entry will be made when
///< the thread starts and stops. The Start() function must be called
///< to actually start the thread.
virtual ~cThread(); virtual ~cThread();
void SetDescription(const char *Description, ...); void SetDescription(const char *Description, ...);
bool Start(void); bool Start(void);
bool Active(void); ///< Actually starts the thread.
bool Running(void);
///< Checks whether the thread is actually running.
static bool EmergencyExit(bool Request = false); static bool EmergencyExit(bool Request = false);
}; };

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: transfer.c 1.28 2005/02/19 14:38:55 kls Exp $ * $Id: transfer.c 1.29 2005/08/13 11:19:46 kls Exp $
*/ */
#include "transfer.h" #include "transfer.h"
@ -21,7 +21,6 @@ cTransfer::cTransfer(int VPid, const int *APids, const int *DPids, const int *SP
ringBuffer = new cRingBufferLinear(TRANSFERBUFSIZE, TS_SIZE * 2, true, "Transfer"); ringBuffer = new cRingBufferLinear(TRANSFERBUFSIZE, TS_SIZE * 2, true, "Transfer");
remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids); remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids);
needsBufferReserve = Setup.UseDolbyDigital && VPid != 0 && DPids && DPids[0] != 0; needsBufferReserve = Setup.UseDolbyDigital && VPid != 0 && DPids && DPids[0] != 0;
active = false;
} }
cTransfer::~cTransfer() cTransfer::~cTransfer()
@ -34,21 +33,17 @@ cTransfer::~cTransfer()
void cTransfer::Activate(bool On) void cTransfer::Activate(bool On)
{ {
if (On) { if (On)
if (!active) Start();
Start(); else
}
else if (active) {
active = false;
Cancel(3); Cancel(3);
}
} }
void cTransfer::Receive(uchar *Data, int Length) void cTransfer::Receive(uchar *Data, int Length)
{ {
if (IsAttached() && active) { if (IsAttached() && Active()) {
int p = ringBuffer->Put(Data, Length); int p = ringBuffer->Put(Data, Length);
if (p != Length && active) if (p != Length && Active())
ringBuffer->ReportOverflow(Length - p); ringBuffer->ReportOverflow(Length - p);
return; return;
} }
@ -70,8 +65,7 @@ void cTransfer::Action(void)
bool GotBufferReserve = false; bool GotBufferReserve = false;
int RequiredBufferReserve = KILOBYTE(DvbCardWith4MBofSDRAM ? 288 : 576); int RequiredBufferReserve = KILOBYTE(DvbCardWith4MBofSDRAM ? 288 : 576);
#endif #endif
active = true; while (Active()) {
while (active) {
#ifdef FW_NEEDS_BUFFER_RESERVE_FOR_AC3 #ifdef FW_NEEDS_BUFFER_RESERVE_FOR_AC3
if (needsBufferReserve && !GotBufferReserve) { if (needsBufferReserve && !GotBufferReserve) {
//XXX For dolby we've to fill the buffer because the firmware does //XXX For dolby we've to fill the buffer because the firmware does
@ -145,7 +139,6 @@ void cTransfer::Action(void)
} }
} }
} }
active = false;
} }
// --- cTransferControl ------------------------------------------------------ // --- cTransferControl ------------------------------------------------------

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: transfer.h 1.9 2005/01/16 12:05:13 kls Exp $ * $Id: transfer.h 1.10 2005/08/13 10:16:02 kls Exp $
*/ */
#ifndef __TRANSFER_H #ifndef __TRANSFER_H
@ -21,7 +21,6 @@ private:
cRingBufferLinear *ringBuffer; cRingBufferLinear *ringBuffer;
cRemux *remux; cRemux *remux;
bool needsBufferReserve; bool needsBufferReserve;
bool active;
protected: protected:
virtual void Activate(bool On); virtual void Activate(bool On);
virtual void Receive(uchar *Data, int Length); virtual void Receive(uchar *Data, int Length);