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

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>
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.

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
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.

View File

@ -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

View File

@ -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();

View File

@ -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,8 +1124,8 @@ bool cDevice::Receiving(bool CheckAny) const
void cDevice::Action(void)
{
if (active && OpenDvr()) {
for (; active;) {
if (Active() && OpenDvr()) {
while (Active()) {
// Read data from the DVR device:
uchar *b = NULL;
if (GetTSPacket(b)) {
@ -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,7 +1254,7 @@ void cTSBuffer::Action(void)
if (ringBuffer) {
bool firstRead = true;
cPoller Poller(f);
for (; active;) {
while (Active()) {
if (firstRead || Poller.Poll(100)) {
firstRead = false;
int r = ringBuffer->Read(f);

View File

@ -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);

View File

@ -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))

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
};

View File

@ -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)
if (On)
Start();
}
else if (active) {
active = false;
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 ------------------------------------------------------

View File

@ -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);