From 610c5600df98b35226536ffe92b1fd231128c7d4 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 1 Apr 2001 18:00:00 +0200 Subject: =?UTF-8?q?Version=200.72=20-=20Fixed=20SVDRP=20commands=20LSTC=20?= =?UTF-8?q?and=20LSTT=20to=20make=20them=20return=20an=20error=20message?= =?UTF-8?q?=20if=20=20=20no=20channels=20or=20timers=20are=20defined.=20-?= =?UTF-8?q?=20Enhanced=20'channels.conf.cable'=20(thanks=20to=20Hans-Peter?= =?UTF-8?q?=20Raschke).=20-=20Fixed=20switching=20to=20another=20channel?= =?UTF-8?q?=20via=20the=20EPG=20while=20a=20recording=20is=20being=20=20?= =?UTF-8?q?=20replayed.=20-=20Fixed=20a=20memory=20leak=20in=20the=20EIT?= =?UTF-8?q?=20processor=20that=20happened=20when=20the=20system=20time=20?= =?UTF-8?q?=20=20was=20set.=20-=20Removed=20some=20redundant=20code=20from?= =?UTF-8?q?=20the=20cListBase=20destructor.=20-=20Fixed=20internationaliza?= =?UTF-8?q?tion=20of=20some=20Main=20menu=20texts.=20-=20Updated=20'channe?= =?UTF-8?q?ls.conf'=20after=20the=20recent=20changes=20of=20Premiere=20Wor?= =?UTF-8?q?ld=20(thanks=20=20=20to=20Axel=20Gruber).=20-=20Redesigned=20th?= =?UTF-8?q?e=20ring=20buffer=20to=20make=20it=20work=20with=20two=20separa?= =?UTF-8?q?te=20threads=20for=20=20=20input=20and=20output=20(also=20prepa?= =?UTF-8?q?red=20for=20using=20a=20remultiplexer).=20-=20Fixed=20setting?= =?UTF-8?q?=20system=20time=20from=20transponders.=20-=20Fixed=20a=20segfa?= =?UTF-8?q?ult=20in=20the=20Schedule=20menu=20in=20case=20there=20is=20no?= =?UTF-8?q?=20EPG=20information.=20-=20The=20'runvdr'=20script=20now=20kil?= =?UTF-8?q?ls=20any=20leftover=20vdr=20threads=20before=20restarting=20it.?= =?UTF-8?q?=20-=20Fixed=20a=20problem=20with=20Daylight=20Saving=20Time=20?= =?UTF-8?q?when=20displaying=20the=20times=20of=20=20=20recordings.=20-=20?= =?UTF-8?q?Added=20Dutch=20language=20texts=20(thanks=20to=20Arnold=20Nies?= =?UTF-8?q?sen).=20-=20The=20new=20command=20line=20option=20-t=20can=20be?= =?UTF-8?q?=20used=20to=20set=20the=20controlling=20terminal=20=20=20(than?= =?UTF-8?q?ks=20to=20J=FCrgen=20Sauer).=20This=20is=20especially=20useful?= =?UTF-8?q?=20when=20starting=20VDR=20through=20=20=20an=20entry=20in=20/e?= =?UTF-8?q?tc/inittab=20(see=20INSTALL).=20-=20Since=20the=20CAM=20module?= =?UTF-8?q?=20only=20works=20if=20it=20is=20installed=20in=20the=20"highes?= =?UTF-8?q?t"=20DVB=20card,=20=20=20recordings=20now=20search=20for=20a=20?= =?UTF-8?q?free=20DVB=20card=20from=20lowest=20to=20highest=20index=20(as?= =?UTF-8?q?=20=20=20opposed=20to=20the=20previous=20"highest=20to=20lowest?= =?UTF-8?q?"=20search)=20in=20order=20to=20not=20use=20the=20=20=20CAM=20c?= =?UTF-8?q?ard=20for=20FTA=20recordings=20unless=20necessary.=20This=20is?= =?UTF-8?q?=20only=20important=20for=20=20=20systems=20with=20three=20or?= =?UTF-8?q?=20more=20DVB=20cards.=20-=20Added=20the=20"statdvb2vdr"=20tool?= =?UTF-8?q?=20from=20Hans-Peter=20Raschke.=20-=20Fixed=20a=20segfault=20th?= =?UTF-8?q?at=20sometimes=20happened=20when=20killing=20VDR.=20-=20VDR=20n?= =?UTF-8?q?ow=20returns=20an=20exit=20status=20of=20'2'=20in=20case=20of?= =?UTF-8?q?=20an=20error=20at=20startup,=20instead=20=20=20of=20terminatin?= =?UTF-8?q?g=20with=20'abort()'=20(which=20caused=20a=20core=20dump).=20-?= =?UTF-8?q?=20SVDRP=20now=20also=20works=20with=20clients=20that=20don't?= =?UTF-8?q?=20do=20line=20buffering=20(like=20the=20=20=20Windows=20'telne?= =?UTF-8?q?t').=20-=20Empty=20lines=20in=20config=20files=20no=20longer=20?= =?UTF-8?q?cause=20error=20messages.=20-=20New=20SVDRP=20command=20LSTE=20?= =?UTF-8?q?to=20list=20the=20EPG=20data.=20-=20The=20SVDRP=20HELP=20comman?= =?UTF-8?q?d=20now=20prints=20the=20topics=20in=20several=20columns.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ringbuffer.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 ringbuffer.c (limited to 'ringbuffer.c') diff --git a/ringbuffer.c b/ringbuffer.c new file mode 100644 index 0000000..4870713 --- /dev/null +++ b/ringbuffer.c @@ -0,0 +1,170 @@ +/* + * ringbuffer.c: A threaded ring buffer + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * Parts of this file were inspired by the 'ringbuffy.c' from the + * LinuxDVB driver (see linuxtv.org). + * + * $Id: ringbuffer.c 1.1 2001/03/10 17:11:34 kls Exp $ + */ + +#include "ringbuffer.h" +#include "tools.h" + +// --- cRingBufferInputThread ------------------------------------------------- + +class cRingBufferInputThread : public cThread { +private: + cRingBuffer *ringBuffer; +protected: + virtual void Action(void) { ringBuffer->Input(); } +public: + cRingBufferInputThread(cRingBuffer *RingBuffer) { ringBuffer = RingBuffer; } + }; + +// --- cRingBufferOutputThread ------------------------------------------------ + +class cRingBufferOutputThread : public cThread { +private: + cRingBuffer *ringBuffer; +protected: + virtual void Action(void) { ringBuffer->Output(); } +public: + cRingBufferOutputThread(cRingBuffer *RingBuffer) { ringBuffer = RingBuffer; } + }; + +// --- cRingBuffer ------------------------------------------------------------ + +cRingBuffer::cRingBuffer(int Size) +{ + size = Size; + buffer = NULL; + inputThread = NULL; + outputThread = NULL; + maxFill = 0; + busy = false; + if (size > 1) { // 'size - 1' must not be 0! + buffer = new uchar[size]; + if (!buffer) + esyslog(LOG_ERR, "ERROR: can't allocate ring buffer (size=%d)", size); + Clear(); + } + else + esyslog(LOG_ERR, "ERROR: illegal size for ring buffer (%d)", size); +} + +cRingBuffer::~cRingBuffer() +{ + delete inputThread; + delete outputThread; + delete buffer; + dsyslog(LOG_INFO, "buffer stats: %d (%d%%) used", maxFill, maxFill * 100 / (size - 1)); +} + +void cRingBuffer::Clear(void) +{ + mutex.Lock(); + head = tail = 0; + mutex.Unlock(); +} + +int cRingBuffer::Put(const uchar *Data, int Count) +{ + if (Count > 0) { + mutex.Lock(); + int rest = size - head; + int diff = tail - head; + mutex.Unlock(); + int free = (diff > 0) ? diff - 1 : size + diff - 1; + // Statistics: + int fill = size - free - 1 + Count; + if (fill >= size) + fill = size - 1; + if (fill > maxFill) { + maxFill = fill; + int percent = maxFill * 100 / (size - 1); + if (percent > 75) + dsyslog(LOG_INFO, "buffer usage: %d%%", percent); + } + // + if (free <= 0) + return 0; + if (free < Count) + Count = free; + if (Count > maxFill) + maxFill = Count; + if (Count >= rest) { + memcpy(buffer + head, Data, rest); + if (Count - rest) + memcpy(buffer, Data + rest, Count - rest); + head = Count - rest; + } + else { + memcpy(buffer + head, Data, Count); + head += Count; + } + } + return Count; +} + +int cRingBuffer::Get(uchar *Data, int Count) +{ + if (Count > 0) { + mutex.Lock(); + int rest = size - tail; + int diff = head - tail; + mutex.Unlock(); + int cont = (diff >= 0) ? diff : size + diff; + if (rest <= 0) + return 0; + if (cont < Count) + Count = cont; + if (Count >= rest) { + memcpy(Data, buffer + tail, rest); + if (Count - rest) + memcpy(Data + rest, buffer, Count - rest); + tail = Count - rest; + } + else { + memcpy(Data, buffer + tail, Count); + tail += Count; + } + } + return Count; +} + +bool cRingBuffer::Start(void) +{ + if (!busy) { + busy = true; + outputThread = new cRingBufferOutputThread(this); + if (!outputThread->Start()) + DELETENULL(outputThread); + inputThread = new cRingBufferInputThread(this); + if (!inputThread->Start()) { + DELETENULL(inputThread); + DELETENULL(outputThread); + } + busy = outputThread && inputThread; + } + return busy; +} + +bool cRingBuffer::Active(void) +{ + return outputThread && outputThread->Active() && inputThread && inputThread->Active(); +} + +void cRingBuffer::Stop(void) +{ + busy = false; + for (time_t t0 = time(NULL) + 3; time(NULL) < t0; ) { + if (!((outputThread && outputThread->Active()) || (inputThread && inputThread->Active()))) + break; + } + DELETENULL(inputThread); + DELETENULL(outputThread); +} + -- cgit v1.2.3