===================================================================
RCS file: ./RCS/cutter.c
retrieving revision 1.8
@@ -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 @@
:cThread("video cutting")
{
error = NULL;
- active = false;
fromFile = toFile = -1;
fromFileName = toFileName = NULL;
fromIndex = toIndex = NULL;
@@ -53,7 +51,6 @@
cCuttingThread::~cCuttingThread()
{
- active = false;
Cancel(3);
delete fromFileName;
delete toFileName;
@@ -67,7 +64,8 @@
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 @@
uchar buffer[MAXFRAMESIZE];
bool LastMark = false;
bool cutIn = true;
- while (active) {
+ while (Running()) {
uchar FileNumber;
int FileOffset, Length;
uchar PictureType;
===================================================================
RCS file: ./RCS/device.c
retrieving revision 1.103
@@ -156,8 +156,6 @@
SetVideoFormat(Setup.VideoFormat);
- active = false;
-
mute = false;
volume = Setup.CurrentVolume;
@@ -1126,25 +1124,25 @@
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 (Running() && OpenDvr()) {
+ while (Running()) {
+ // 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 @@
Receiver->device = this;
receiver[i] = Receiver;
Unlock();
- if (!active) {
- active = true;
+ if (!Running())
Start();
- }
return true;
}
}
@@ -1218,10 +1214,8 @@
else if (receiver[i])
receiversLeft = true;
}
- if (!receiversLeft) {
- active = false;
+ if (!receiversLeft)
Cancel(3);
- }
}
void cDevice::DetachAll(int Pid)
@@ -1246,13 +1240,11 @@
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 @@
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 (Running()) {
+ 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;
+ }
+ }
+ }
+ }
}
}
===================================================================
RCS file: ./RCS/device.h
retrieving revision 1.60
@@ -233,7 +233,6 @@
// PID handle facilities
private:
- bool active;
virtual void Action(void);
protected:
enum ePidType { ptAudio, ptVideo, ptPcr, ptTeletext, ptDolby, ptOther };
@@ -518,7 +517,6 @@
private:
int f;
int cardIndex;
- bool active;
bool delivered;
cRingBufferLinear *ringBuffer;
virtual void Action(void);
===================================================================
RCS file: ./RCS/dvbdevice.c
retrieving revision 1.131
@@ -76,7 +76,6 @@
cCiHandler *ciHandler;
cChannel channel;
const char *diseqcCommands;
- bool active;
bool useCa;
time_t startTime;
eTunerStatus tunerStatus;
@@ -101,7 +100,6 @@
frontendType = FrontendType;
ciHandler = CiHandler;
diseqcCommands = NULL;
- active = false;
useCa = false;
tunerStatus = tsIdle;
startTime = time(NULL);
@@ -113,7 +111,6 @@
cDvbTuner::~cDvbTuner()
{
- active = false;
tunerStatus = tsIdle;
newSet.Signal();
Cancel(3);
@@ -294,8 +291,7 @@
void cDvbTuner::Action(void)
{
dvb_frontend_event event;
- active = true;
- while (active) {
+ while (Running()) {
Lock();
if (tunerStatus == tsSet) {
while (GetFrontendEvent(event))
===================================================================
RCS file: ./RCS/dvbplayer.c
retrieving revision 1.36
@@ -79,7 +79,6 @@
int wanted;
int length;
bool hasData;
- bool active;
cCondWait newSet;
protected:
void Action(void);
@@ -98,13 +97,11 @@
buffer = NULL;
wanted = length = 0;
hasData = false;
- active = false;
Start();
}
cNonBlockingFileReader::~cNonBlockingFileReader()
{
- active = false;
newSet.Signal();
Cancel(3);
free(buffer);
@@ -147,8 +144,7 @@
void cNonBlockingFileReader::Action(void)
{
- active = true;
- while (active) {
+ while (Running()) {
Lock();
if (!hasData && f >= 0 && buffer) {
int r = safe_read(f, buffer + length, wanted - length);
@@ -187,8 +183,6 @@
cIndexFile *index;
int replayFile;
bool eof;
- bool active;
- bool running;
bool firstPacket;
ePlayModes playMode;
ePlayDirs playDir;
@@ -207,7 +201,7 @@
public:
cDvbPlayer(const char *FileName);
virtual ~cDvbPlayer();
- bool Active(void) { return active; }
+ bool Active(void) { return cThread::Running(); }
void Pause(void);
void Play(void);
void Forward(void);
@@ -233,8 +227,6 @@
backTrace = NULL;
index = NULL;
eof = false;
- active = true;
- running = false;
firstPacket = true;
playMode = pmPlay;
playDir = pdForward;
@@ -353,11 +345,8 @@
if (replayFile >= 0)
Start();
}
- else if (active) {
- running = false;
+ else
Cancel(9);
- active = false;
- }
}
void cDvbPlayer::Action(void)
@@ -374,8 +363,7 @@
int Length = 0;
bool Sleep = false;
- running = true;
- while (running && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) {
+ while (Running() && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) {
if (Sleep) {
cCondWait::SleepMs(3); // this keeps the CPU load low
Sleep = false;
@@ -501,7 +489,6 @@
Sleep = true;
}
}
- active = running = false;
cNonBlockingFileReader *nbfr = nonBlockingFileReader;
nonBlockingFileReader = NULL;
===================================================================
RCS file: ./RCS/recorder.c
retrieving revision 1.13
@@ -29,7 +29,6 @@
uchar pictureType;
int fileSize;
int recordFile;
- bool active;
time_t lastDiskSpaceCheck;
bool RunningLowOnDiskSpace(void);
bool NextFile(void);
@@ -43,7 +42,6 @@
cFileWriter::cFileWriter(const char *FileName, cRemux *Remux)
:cThread("file writer")
{
- active = false;
fileName = NULL;
remux = Remux;
index = NULL;
@@ -63,7 +61,6 @@
cFileWriter::~cFileWriter()
{
- active = false;
Cancel(3);
delete index;
delete fileName;
@@ -96,13 +93,11 @@
void cFileWriter::Action(void)
{
time_t t = time(NULL);
- active = true;
- while (active) {
+ while (Running()) {
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 (!Running() && pictureType == I_FRAME) // finish the recording before the next 'I' frame
break;
if (NextFile()) {
if (index && pictureType != NO_PICTURE)
@@ -124,15 +119,12 @@
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 @@
writer->Start();
Start();
}
- else if (active) {
- active = false;
+ else
Cancel(3);
- }
}
void cRecorder::Receive(uchar *Data, int Length)
{
- if (active) {
+ if (Running()) {
int p = ringBuffer->Put(Data, Length);
- if (p != Length && active)
+ if (p != Length && Running())
ringBuffer->ReportOverflow(Length - p);
}
}
void cRecorder::Action(void)
{
- active = true;
- while (active) {
+ while (Running()) {
int r;
uchar *b = ringBuffer->Get(r);
if (b) {
===================================================================
RCS file: ./RCS/recorder.h
retrieving revision 1.3
@@ -23,7 +23,6 @@
cRingBufferLinear *ringBuffer;
cRemux *remux;
cFileWriter *writer;
- bool active;
protected:
virtual void Activate(bool On);
virtual void Receive(uchar *Data, int Length);
===================================================================
RCS file: ./RCS/remote.c
retrieving revision 1.42
@@ -213,7 +213,6 @@
: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()
{
kbdAvailable = false;
- active = false;
Cancel(3);
tcsetattr(STDIN_FILENO, TCSANOW, &savedTm);
}
@@ -261,12 +259,11 @@
void cKbdRemote::Action(void)
{
cPoller Poller(STDIN_FILENO);
- active = true;
- while (active) {
+ while (Running()) {
if (Poller.Poll(100)) {
uint64 Command = 0;
uint i = 0;
- while (active && i < sizeof(Command)) {
+ while (Running() && i < sizeof(Command)) {
uchar ch;
int r = read(STDIN_FILENO, &ch, 1);
if (r == 1) {
===================================================================
RCS file: ./RCS/remote.h
retrieving revision 1.29
@@ -81,7 +81,6 @@
class cKbdRemote : public cRemote, private cThread {
private:
- bool active;
static bool kbdAvailable;
static bool rawMode;
struct termios savedTm;
===================================================================
RCS file: ./RCS/sections.c
retrieving revision 1.11
@@ -44,7 +44,6 @@
{
shp = new cSectionHandlerPrivate;
device = Device;
- active = false;
statusCount = 0;
on = false;
waitForLock = false;
@@ -54,7 +53,6 @@
cSectionHandler::~cSectionHandler()
{
- active = false;
Cancel(3);
cFilter *fi;
while ((fi = filters.First()) != NULL)
@@ -166,9 +164,8 @@
void cSectionHandler::Action(void)
{
- active = true;
SetPriority(19);
- while (active) {
+ while (Running()) {
Lock();
if (waitForLock)
===================================================================
RCS file: ./RCS/sections.h
retrieving revision 1.4
@@ -25,7 +25,6 @@
private:
cSectionHandlerPrivate *shp;
cDevice *device;
- bool active;
int statusCount;
bool on, waitForLock;
time_t lastIncompleteSection;
===================================================================
RCS file: ./RCS/thread.c
retrieving revision 1.43
@@ -197,7 +197,7 @@
cThread::cThread(const char *Description)
{
- running = false;
+ active = running = false;
childTid = 0;
description = NULL;
SetDescription(Description);
@@ -205,6 +205,7 @@
cThread::~cThread()
{
+ Cancel(); // just in case the derived class didn't call it
free(description);
}
@@ -234,20 +235,21 @@
if (Thread->description)
dsyslog("%s thread ended (pid=%d, tid=%ld)", Thread->description, getpid(), pthread_self());
Thread->running = false;
+ Thread->active = false;
return NULL;
}
bool cThread::Start(void)
{
- if (!running) {
- running = true;
+ if (!active) {
+ active = running = 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;
+ active = running = false;
return false;
}
}
@@ -256,7 +258,7 @@
bool cThread::Active(void)
{
- if (running) {
+ if (active) {
//
// Single UNIX Spec v2 says:
//
@@ -271,7 +273,7 @@
if (err != ESRCH)
LOG_ERROR;
childTid = 0;
- running = false;
+ active = running = false;
}
else
return true;
@@ -281,7 +283,8 @@
void cThread::Cancel(int WaitSeconds)
{
- if (running) {
+ running = false;
+ if (active) {
if (WaitSeconds > 0) {
for (time_t t0 = time(NULL) + WaitSeconds; time(NULL) < t0; ) {
if (!Active())
@@ -292,7 +295,7 @@
}
pthread_cancel(childTid);
childTid = 0;
- running = false;
+ active = false;
}
}
===================================================================
RCS file: ./RCS/thread.h
retrieving revision 1.28
@@ -75,6 +75,7 @@
class cThread {
friend class cThreadLock;
private:
+ bool active;
bool running;
pthread_t childTid;
cMutex mutex;
@@ -86,13 +87,30 @@
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 Running() repeatedly to see whether
+ ///< it's time to stop.
+ bool Running(void) { return running; }
+ ///< Returns false if a derived cThread object shall leave its Action()
+ ///< function.
void Cancel(int WaitSeconds = 0);
+ ///< Cancels the thread by first setting 'running' 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);
+ ///< Actually starts the thread.
bool Active(void);
+ ///< Checks whether the thread is still alive.
static bool EmergencyExit(bool Request = false);
};
===================================================================
RCS file: ./RCS/transfer.c
retrieving revision 1.28
@@ -21,7 +21,6 @@
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 @@
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() && Running()) {
int p = ringBuffer->Put(Data, Length);
- if (p != Length && active)
+ if (p != Length && Running())
ringBuffer->ReportOverflow(Length - p);
return;
}
@@ -70,8 +65,7 @@
bool GotBufferReserve = false;
int RequiredBufferReserve = KILOBYTE(DvbCardWith4MBofSDRAM ? 288 : 576);
#endif
- active = true;
- while (active) {
+ while (Running()) {
#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 @@
}
}
}
- active = false;
}
// --- cTransferControl ------------------------------------------------------
===================================================================
RCS file: ./RCS/transfer.h
retrieving revision 1.9
@@ -21,7 +21,6 @@
cRingBufferLinear *ringBuffer;
cRemux *remux;
bool needsBufferReserve;
- bool active;
protected:
virtual void Activate(bool On);
virtual void Receive(uchar *Data, int Length);