summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2005-08-13 13:17:24 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2005-08-13 13:17:24 +0200
commitccb0add798961ce2fa24f625a00106cb0d3df709 (patch)
tree43e50aa8938a53236d90e260700e83296b26987d
parent1921c7465fd72d8507b11230729754a17761c7e1 (diff)
downloadvdr-ccb0add798961ce2fa24f625a00106cb0d3df709.tar.gz
vdr-ccb0add798961ce2fa24f625a00106cb0d3df709.tar.bz2
Centralized 'thread active' handling
-rw-r--r--CONTRIBUTORS3
-rw-r--r--HISTORY9
-rw-r--r--config.h6
-rw-r--r--cutter.c14
-rw-r--r--device.c80
-rw-r--r--device.h4
-rw-r--r--dvbdevice.c8
-rw-r--r--dvbplayer.c23
-rw-r--r--recorder.c25
-rw-r--r--recorder.h3
-rw-r--r--remote.c9
-rw-r--r--remote.h3
-rw-r--r--sections.c7
-rw-r--r--sections.h3
-rw-r--r--thread.c17
-rw-r--r--thread.h22
-rw-r--r--transfer.c21
-rw-r--r--transfer.h3
18 files changed, 118 insertions, 142 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 770a0807..bbc80c32 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -1417,3 +1417,6 @@ Frank Krömmelbein <kroemmelbein@gmx.de>
Bernhard Stegmaier <bernhard.stegmaier@in.tum.de>
for reporting a problem in cEITScanner::Process() with forced EPG scans if EPG
scan timeout is set to 0
+
+Klaus ??? <klaus@reel-multimedia.com>
+ for reporting a race condition in cTransfer.
diff --git a/HISTORY b/HISTORY
index 5ec6d833..bdf5f905 100644
--- a/HISTORY
+++ b/HISTORY
@@ -3671,3 +3671,12 @@ Video Disk Recorder Revision History
- Fixed setting system time to avoid time jumps in case of faulty data (thanks
to Andreas Böttger).
- 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.
diff --git a/config.h b/config.h
index cce09e9e..57eed300 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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
@@ -20,8 +20,8 @@
#include "i18n.h"
#include "tools.h"
-#define VDRVERSION "1.3.28"
-#define VDRVERSNUM 10328 // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION "1.3.29"
+#define VDRVERSNUM 10329 // Version * 10000 + Major * 100 + Minor
#define MAXPRIORITY 99
#define MAXLIFETIME 99
diff --git a/cutter.c b/cutter.c
index 82c7fe5b..59c6fb86 100644
--- a/cutter.c
+++ b/cutter.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@@ -18,7 +18,6 @@
class cCuttingThread : public cThread {
private:
const char *error;
- bool active;
int fromFile, toFile;
cFileName *fromFileName, *toFileName;
cIndexFile *fromIndex, *toIndex;
@@ -35,7 +34,6 @@ cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName)
:cThread("video cutting")
{
error = NULL;
- active = false;
fromFile = toFile = -1;
fromFileName = toFileName = NULL;
fromIndex = toIndex = NULL;
@@ -53,7 +51,6 @@ cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName)
cCuttingThread::~cCuttingThread()
{
- active = false;
Cancel(3);
delete fromFileName;
delete toFileName;
@@ -67,7 +64,8 @@ void cCuttingThread::Action(void)
if (Mark) {
fromFile = fromFileName->Open();
toFile = toFileName->Open();
- active = fromFile >= 0 && toFile >= 0;
+ if (fromFile < 0 || toFile < 0)
+ return;
int Index = Mark->position;
Mark = fromMarks.Next(Mark);
int FileSize = 0;
@@ -78,7 +76,7 @@ void cCuttingThread::Action(void)
uchar buffer[MAXFRAMESIZE];
bool LastMark = false;
bool cutIn = true;
- while (active) {
+ while (Active()) {
uchar FileNumber;
int FileOffset, Length;
uchar PictureType;
@@ -215,7 +213,7 @@ bool cCutter::Start(const char *FileName)
void cCutter::Stop(void)
{
- bool Interrupted = cuttingThread && cuttingThread->Active();
+ bool Interrupted = cuttingThread && cuttingThread->Running();
const char *Error = cuttingThread ? cuttingThread->Error() : NULL;
delete cuttingThread;
cuttingThread = NULL;
@@ -232,7 +230,7 @@ void cCutter::Stop(void)
bool cCutter::Active(void)
{
if (cuttingThread) {
- if (cuttingThread->Active())
+ if (cuttingThread->Running())
return true;
error = cuttingThread->Error();
Stop();
diff --git a/device.c b/device.c
index c79f7db3..c9227f92 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@@ -156,8 +156,6 @@ cDevice::cDevice(void)
SetVideoFormat(Setup.VideoFormat);
- active = false;
-
mute = false;
volume = Setup.CurrentVolume;
@@ -1126,25 +1124,25 @@ bool cDevice::Receiving(bool CheckAny) const
void cDevice::Action(void)
{
- if (active && OpenDvr()) {
- for (; active;) {
- // Read data from the DVR device:
- uchar *b = NULL;
- if (GetTSPacket(b)) {
- if (b) {
- int Pid = (((uint16_t)b[1] & PID_MASK_HI) << 8) | b[2];
- // Distribute the packet to all attached receivers:
- Lock();
- for (int i = 0; i < MAXRECEIVERS; i++) {
- if (receiver[i] && receiver[i]->WantsPid(Pid))
- receiver[i]->Receive(b, TS_SIZE);
- }
- Unlock();
- }
- }
- else
- break;
- }
+ if (Active() && OpenDvr()) {
+ while (Active()) {
+ // Read data from the DVR device:
+ uchar *b = NULL;
+ if (GetTSPacket(b)) {
+ if (b) {
+ int Pid = (((uint16_t)b[1] & PID_MASK_HI) << 8) | b[2];
+ // Distribute the packet to all attached receivers:
+ Lock();
+ for (int i = 0; i < MAXRECEIVERS; i++) {
+ if (receiver[i] && receiver[i]->WantsPid(Pid))
+ receiver[i]->Receive(b, TS_SIZE);
+ }
+ Unlock();
+ }
+ }
+ else
+ break;
+ }
CloseDvr();
}
}
@@ -1188,10 +1186,8 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
Receiver->device = this;
receiver[i] = Receiver;
Unlock();
- if (!active) {
- active = true;
+ if (!Active())
Start();
- }
return true;
}
}
@@ -1218,10 +1214,8 @@ void cDevice::Detach(cReceiver *Receiver)
else if (receiver[i])
receiversLeft = true;
}
- if (!receiversLeft) {
- active = false;
+ if (!receiversLeft)
Cancel(3);
- }
}
void cDevice::DetachAll(int Pid)
@@ -1246,13 +1240,11 @@ cTSBuffer::cTSBuffer(int File, int Size, int CardIndex)
delivered = false;
ringBuffer = new cRingBufferLinear(Size, TS_SIZE, true, "TS");
ringBuffer->SetTimeouts(100, 100);
- active = true;
Start();
}
cTSBuffer::~cTSBuffer()
{
- active = false;
Cancel(3);
delete ringBuffer;
}
@@ -1262,20 +1254,20 @@ void cTSBuffer::Action(void)
if (ringBuffer) {
bool firstRead = true;
cPoller Poller(f);
- for (; active;) {
- if (firstRead || Poller.Poll(100)) {
- firstRead = false;
- int r = ringBuffer->Read(f);
- if (r < 0 && FATALERRNO) {
- if (errno == EOVERFLOW)
- esyslog("ERROR: driver buffer overflow on device %d", cardIndex);
- else {
- LOG_ERROR;
- break;
- }
- }
- }
- }
+ while (Active()) {
+ if (firstRead || Poller.Poll(100)) {
+ firstRead = false;
+ int r = ringBuffer->Read(f);
+ if (r < 0 && FATALERRNO) {
+ if (errno == EOVERFLOW)
+ esyslog("ERROR: driver buffer overflow on device %d", cardIndex);
+ else {
+ LOG_ERROR;
+ break;
+ }
+ }
+ }
+ }
}
}
diff --git a/device.h b/device.h
index 70092a9a..fc9ba3a1 100644
--- a/device.h
+++ b/device.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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
@@ -233,7 +233,6 @@ public:
// PID handle facilities
private:
- bool active;
virtual void Action(void);
protected:
enum ePidType { ptAudio, ptVideo, ptPcr, ptTeletext, ptDolby, ptOther };
@@ -518,7 +517,6 @@ class cTSBuffer : public cThread {
private:
int f;
int cardIndex;
- bool active;
bool delivered;
cRingBufferLinear *ringBuffer;
virtual void Action(void);
diff --git a/dvbdevice.c b/dvbdevice.c
index 8a25adb4..d81090ca 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.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"
@@ -76,7 +76,6 @@ private:
cCiHandler *ciHandler;
cChannel channel;
const char *diseqcCommands;
- bool active;
bool useCa;
time_t startTime;
eTunerStatus tunerStatus;
@@ -101,7 +100,6 @@ cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType, cCi
frontendType = FrontendType;
ciHandler = CiHandler;
diseqcCommands = NULL;
- active = false;
useCa = false;
tunerStatus = tsIdle;
startTime = time(NULL);
@@ -113,7 +111,6 @@ cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType, cCi
cDvbTuner::~cDvbTuner()
{
- active = false;
tunerStatus = tsIdle;
newSet.Signal();
Cancel(3);
@@ -294,8 +291,7 @@ bool cDvbTuner::SetFrontend(void)
void cDvbTuner::Action(void)
{
dvb_frontend_event event;
- active = true;
- while (active) {
+ while (Active()) {
Lock();
if (tunerStatus == tsSet) {
while (GetFrontendEvent(event))
diff --git a/dvbplayer.c b/dvbplayer.c
index cd002a77..8763ac82 100644
--- a/dvbplayer.c
+++ b/dvbplayer.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@@ -79,7 +79,6 @@ private:
int wanted;
int length;
bool hasData;
- bool active;
cCondWait newSet;
protected:
void Action(void);
@@ -98,13 +97,11 @@ cNonBlockingFileReader::cNonBlockingFileReader(void)
buffer = NULL;
wanted = length = 0;
hasData = false;
- active = false;
Start();
}
cNonBlockingFileReader::~cNonBlockingFileReader()
{
- active = false;
newSet.Signal();
Cancel(3);
free(buffer);
@@ -147,8 +144,7 @@ int cNonBlockingFileReader::Read(int FileHandle, uchar *Buffer, int Length)
void cNonBlockingFileReader::Action(void)
{
- active = true;
- while (active) {
+ while (Active()) {
Lock();
if (!hasData && f >= 0 && buffer) {
int r = safe_read(f, buffer + length, wanted - length);
@@ -187,8 +183,6 @@ private:
cIndexFile *index;
int replayFile;
bool eof;
- bool active;
- bool running;
bool firstPacket;
ePlayModes playMode;
ePlayDirs playDir;
@@ -207,7 +201,7 @@ protected:
public:
cDvbPlayer(const char *FileName);
virtual ~cDvbPlayer();
- bool Active(void) { return active; }
+ bool Active(void) { return cThread::Active(); }
void Pause(void);
void Play(void);
void Forward(void);
@@ -233,8 +227,6 @@ cDvbPlayer::cDvbPlayer(const char *FileName)
backTrace = NULL;
index = NULL;
eof = false;
- active = true;
- running = false;
firstPacket = true;
playMode = pmPlay;
playDir = pdForward;
@@ -353,11 +345,8 @@ void cDvbPlayer::Activate(bool On)
if (replayFile >= 0)
Start();
}
- else if (active) {
- running = false;
+ else
Cancel(9);
- active = false;
- }
}
void cDvbPlayer::Action(void)
@@ -374,8 +363,7 @@ void cDvbPlayer::Action(void)
int Length = 0;
bool Sleep = false;
- running = true;
- while (running && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) {
+ while (Active() && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) {
if (Sleep) {
cCondWait::SleepMs(3); // this keeps the CPU load low
Sleep = false;
@@ -501,7 +489,6 @@ void cDvbPlayer::Action(void)
Sleep = true;
}
}
- active = running = false;
cNonBlockingFileReader *nbfr = nonBlockingFileReader;
nonBlockingFileReader = NULL;
diff --git a/recorder.c b/recorder.c
index dd3f4f60..253d8391 100644
--- a/recorder.c
+++ b/recorder.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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>
@@ -29,7 +29,6 @@ private:
uchar pictureType;
int fileSize;
int recordFile;
- bool active;
time_t lastDiskSpaceCheck;
bool RunningLowOnDiskSpace(void);
bool NextFile(void);
@@ -43,7 +42,6 @@ public:
cFileWriter::cFileWriter(const char *FileName, cRemux *Remux)
:cThread("file writer")
{
- active = false;
fileName = NULL;
remux = Remux;
index = NULL;
@@ -63,7 +61,6 @@ cFileWriter::cFileWriter(const char *FileName, cRemux *Remux)
cFileWriter::~cFileWriter()
{
- active = false;
Cancel(3);
delete index;
delete fileName;
@@ -96,13 +93,11 @@ bool cFileWriter::NextFile(void)
void cFileWriter::Action(void)
{
time_t t = time(NULL);
- active = true;
- while (active) {
+ while (Active()) {
int Count;
uchar *p = remux->Get(Count, &pictureType);
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;
if (NextFile()) {
if (index && pictureType != NO_PICTURE)
@@ -124,15 +119,12 @@ void cFileWriter::Action(void)
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)
:cReceiver(Ca, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids)
,cThread("recording")
{
- active = false;
-
// Make sure the disk is up and running:
SpinUpDisk(FileName);
@@ -157,25 +149,22 @@ void cRecorder::Activate(bool On)
writer->Start();
Start();
}
- else if (active) {
- active = false;
+ else
Cancel(3);
- }
}
void cRecorder::Receive(uchar *Data, int Length)
{
- if (active) {
+ if (Active()) {
int p = ringBuffer->Put(Data, Length);
- if (p != Length && active)
+ if (p != Length && Active())
ringBuffer->ReportOverflow(Length - p);
}
}
void cRecorder::Action(void)
{
- active = true;
- while (active) {
+ while (Active()) {
int r;
uchar *b = ringBuffer->Get(r);
if (b) {
diff --git a/recorder.h b/recorder.h
index da7934bf..c4aebbf3 100644
--- a/recorder.h
+++ b/recorder.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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
@@ -23,7 +23,6 @@ private:
cRingBufferLinear *ringBuffer;
cRemux *remux;
cFileWriter *writer;
- bool active;
protected:
virtual void Activate(bool On);
virtual void Receive(uchar *Data, int Length);
diff --git a/remote.c b/remote.c
index 448d5530..70256094 100644
--- a/remote.c
+++ b/remote.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@@ -213,7 +213,6 @@ cKbdRemote::cKbdRemote(void)
:cRemote("KBD")
,cThread("KBD remote control")
{
- active = false;
tcgetattr(STDIN_FILENO, &savedTm);
struct termios tm;
if (tcgetattr(STDIN_FILENO, &tm) == 0) {
@@ -230,7 +229,6 @@ cKbdRemote::cKbdRemote(void)
cKbdRemote::~cKbdRemote()
{
kbdAvailable = false;
- active = false;
Cancel(3);
tcsetattr(STDIN_FILENO, TCSANOW, &savedTm);
}
@@ -261,12 +259,11 @@ int cKbdRemote::MapCodeToFunc(uint64 Code)
void cKbdRemote::Action(void)
{
cPoller Poller(STDIN_FILENO);
- active = true;
- while (active) {
+ while (Active()) {
if (Poller.Poll(100)) {
uint64 Command = 0;
uint i = 0;
- while (active && i < sizeof(Command)) {
+ while (Active() && i < sizeof(Command)) {
uchar ch;
int r = read(STDIN_FILENO, &ch, 1);
if (r == 1) {
diff --git a/remote.h b/remote.h
index 2ef206f2..995aa6cd 100644
--- a/remote.h
+++ b/remote.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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
@@ -81,7 +81,6 @@ enum eKbdFunc {
class cKbdRemote : public cRemote, private cThread {
private:
- bool active;
static bool kbdAvailable;
static bool rawMode;
struct termios savedTm;
diff --git a/sections.c b/sections.c
index 6552d56e..8364b409 100644
--- a/sections.c
+++ b/sections.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@@ -44,7 +44,6 @@ cSectionHandler::cSectionHandler(cDevice *Device)
{
shp = new cSectionHandlerPrivate;
device = Device;
- active = false;
statusCount = 0;
on = false;
waitForLock = false;
@@ -54,7 +53,6 @@ cSectionHandler::cSectionHandler(cDevice *Device)
cSectionHandler::~cSectionHandler()
{
- active = false;
Cancel(3);
cFilter *fi;
while ((fi = filters.First()) != NULL)
@@ -166,9 +164,8 @@ void cSectionHandler::SetStatus(bool On)
void cSectionHandler::Action(void)
{
- active = true;
SetPriority(19);
- while (active) {
+ while (Active()) {
Lock();
if (waitForLock)
diff --git a/sections.h b/sections.h
index 0b2b5bdf..f11f4794 100644
--- a/sections.h
+++ b/sections.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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
@@ -25,7 +25,6 @@ class cSectionHandler : public cThread {
private:
cSectionHandlerPrivate *shp;
cDevice *device;
- bool active;
int statusCount;
bool on, waitForLock;
time_t lastIncompleteSection;
diff --git a/thread.c b/thread.c
index 9ac1b7ef..2944678c 100644
--- a/thread.c
+++ b/thread.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@@ -197,7 +197,7 @@ bool cThread::emergencyExitRequested = false;
cThread::cThread(const char *Description)
{
- running = false;
+ running = active = false;
childTid = 0;
description = NULL;
SetDescription(Description);
@@ -205,6 +205,7 @@ cThread::cThread(const char *Description)
cThread::~cThread()
{
+ Cancel(); // just in case the derived class didn't call it
free(description);
}
@@ -233,6 +234,7 @@ void *cThread::StartThread(cThread *Thread)
Thread->Action();
if (Thread->description)
dsyslog("%s thread ended (pid=%d, tid=%ld)", Thread->description, getpid(), pthread_self());
+ Thread->active = false;
Thread->running = false;
return NULL;
}
@@ -240,21 +242,21 @@ void *cThread::StartThread(cThread *Thread)
bool cThread::Start(void)
{
if (!running) {
- running = true;
+ running = active = true;
if (pthread_create(&childTid, NULL, (void *(*) (void *))&StartThread, (void *)this) == 0) {
pthread_detach(childTid); // auto-reap
pthread_setschedparam(childTid, SCHED_RR, 0);
}
else {
LOG_ERROR;
- running = false;
+ running = active = false;
return false;
}
}
return true;
}
-bool cThread::Active(void)
+bool cThread::Running(void)
{
if (running) {
//
@@ -271,7 +273,7 @@ bool cThread::Active(void)
if (err != ESRCH)
LOG_ERROR;
childTid = 0;
- running = false;
+ running = active = false;
}
else
return true;
@@ -281,10 +283,11 @@ bool cThread::Active(void)
void cThread::Cancel(int WaitSeconds)
{
+ active = false;
if (running) {
if (WaitSeconds > 0) {
for (time_t t0 = time(NULL) + WaitSeconds; time(NULL) < t0; ) {
- if (!Active())
+ if (!Running())
return;
cCondWait::SleepMs(10);
}
diff --git a/thread.h b/thread.h
index 48d04990..35b2fee1 100644
--- a/thread.h
+++ b/thread.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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
@@ -76,6 +76,7 @@ class cThread {
friend class cThreadLock;
private:
bool running;
+ bool active;
pthread_t childTid;
cMutex mutex;
char *description;
@@ -86,13 +87,30 @@ protected:
void Lock(void) { mutex.Lock(); }
void Unlock(void) { mutex.Unlock(); }
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);
+ ///< 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:
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();
void SetDescription(const char *Description, ...);
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);
};
diff --git a/transfer.c b/transfer.c
index c214b88f..89143c47 100644
--- a/transfer.c
+++ b/transfer.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@@ -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");
remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids);
needsBufferReserve = Setup.UseDolbyDigital && VPid != 0 && DPids && DPids[0] != 0;
- active = false;
}
cTransfer::~cTransfer()
@@ -34,21 +33,17 @@ cTransfer::~cTransfer()
void cTransfer::Activate(bool On)
{
- if (On) {
- if (!active)
- Start();
- }
- else if (active) {
- active = false;
+ if (On)
+ Start();
+ else
Cancel(3);
- }
}
void cTransfer::Receive(uchar *Data, int Length)
{
- if (IsAttached() && active) {
+ if (IsAttached() && Active()) {
int p = ringBuffer->Put(Data, Length);
- if (p != Length && active)
+ if (p != Length && Active())
ringBuffer->ReportOverflow(Length - p);
return;
}
@@ -70,8 +65,7 @@ void cTransfer::Action(void)
bool GotBufferReserve = false;
int RequiredBufferReserve = KILOBYTE(DvbCardWith4MBofSDRAM ? 288 : 576);
#endif
- active = true;
- while (active) {
+ while (Active()) {
#ifdef FW_NEEDS_BUFFER_RESERVE_FOR_AC3
if (needsBufferReserve && !GotBufferReserve) {
//XXX For dolby we've to fill the buffer because the firmware does
@@ -145,7 +139,6 @@ void cTransfer::Action(void)
}
}
}
- active = false;
}
// --- cTransferControl ------------------------------------------------------
diff --git a/transfer.h b/transfer.h
index 377ecbef..fa88f122 100644
--- a/transfer.h
+++ b/transfer.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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
@@ -21,7 +21,6 @@ private:
cRingBufferLinear *ringBuffer;
cRemux *remux;
bool needsBufferReserve;
- bool active;
protected:
virtual void Activate(bool On);
virtual void Receive(uchar *Data, int Length);