From 1c1fdc5a3f1096c7b2649a6817102685574671a5 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Mon, 12 May 2003 17:46:34 +0200 Subject: [PATCH] Re-implemented the WaitForPut/WaitForGet stuff in cRingBuffer, since some plugins actually need this --- HISTORY | 5 ++++- ringbuffer.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- ringbuffer.h | 11 ++++++++++- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/HISTORY b/HISTORY index 550be80a..34d8901f 100644 --- a/HISTORY +++ b/HISTORY @@ -2143,7 +2143,10 @@ Video Disk Recorder Revision History - Changed C++ style comments in libdtv into C style to avoid warnings in gcc 3.x (thanks to Andreas Schultz). -2003-05-11: Version 1.1.32 +2003-05-12: Version 1.1.32 - Removed a faulty parameter initialization in menu.c (thanks to Lauri Tischler for reporting this one). +- Re-implemented the WaitForPut/WaitForGet stuff in cRingBuffer, since some plugins + actually need this. By default the buffer does not wait; if a plugin needs the + waiting functionality it can call the new SetTimeouts() function. diff --git a/ringbuffer.c b/ringbuffer.c index 770b7c34..2cf9d75d 100644 --- a/ringbuffer.c +++ b/ringbuffer.c @@ -7,7 +7,7 @@ * Parts of this file were inspired by the 'ringbuffy.c' from the * LinuxDVB driver (see linuxtv.org). * - * $Id: ringbuffer.c 1.16 2003/05/11 09:47:56 kls Exp $ + * $Id: ringbuffer.c 1.17 2003/05/12 17:38:11 kls Exp $ */ #include "ringbuffer.h" @@ -23,6 +23,7 @@ cRingBuffer::cRingBuffer(int Size, bool Statistics) statistics = Statistics; maxFill = 0; lastPercent = 0; + putTimeout = getTimeout = 0; } cRingBuffer::~cRingBuffer() @@ -31,6 +32,42 @@ cRingBuffer::~cRingBuffer() dsyslog("buffer stats: %d (%d%%) used", maxFill, maxFill * 100 / (size - 1)); } +void cRingBuffer::WaitForPut(void) +{ + if (putTimeout) { + putMutex.Lock(); + readyForPut.TimedWait(putMutex, putTimeout); + putMutex.Unlock(); + } +} + +void cRingBuffer::WaitForGet(void) +{ + if (getTimeout) { + getMutex.Lock(); + readyForGet.TimedWait(getMutex, getTimeout); + getMutex.Unlock(); + } +} + +void cRingBuffer::EnablePut(void) +{ + if (putTimeout) + readyForPut.Broadcast(); +} + +void cRingBuffer::EnableGet(void) +{ + if (getTimeout) + readyForGet.Broadcast(); +} + +void cRingBuffer::SetTimeouts(int PutTimeout, int GetTimeout) +{ + putTimeout = PutTimeout; + getTimeout = GetTimeout; +} + // --- cRingBufferLinear ----------------------------------------------------- cRingBufferLinear::cRingBufferLinear(int Size, int Margin, bool Statistics) @@ -68,6 +105,8 @@ void cRingBufferLinear::Clear(void) head = tail = margin; lastGet = -1; Unlock(); + EnablePut(); + EnableGet(); } int cRingBufferLinear::Put(const uchar *Data, int Count) @@ -109,6 +148,9 @@ int cRingBufferLinear::Put(const uchar *Data, int Count) else Count = 0; Unlock(); + EnableGet(); + if (Count == 0) + WaitForPut(); } return Count; } @@ -134,6 +176,8 @@ uchar *cRingBufferLinear::Get(int &Count) Count = lastGet = cont; } Unlock(); + if (!p) + WaitForGet(); return p; } @@ -146,6 +190,7 @@ void cRingBufferLinear::Del(int Count) if (tail >= Size()) tail = margin; Unlock(); + EnablePut(); } else esyslog("ERROR: invalid Count in cRingBufferLinear::Del: %d", Count); @@ -196,6 +241,8 @@ void cRingBufferFrame::Clear(void) while ((p = Get()) != NULL) Drop(p); Unlock(); + EnablePut(); + EnableGet(); } bool cRingBufferFrame::Put(cFrame *Frame) @@ -212,6 +259,7 @@ bool cRingBufferFrame::Put(cFrame *Frame) } currentFill += Frame->Count(); Unlock(); + EnableGet(); return true; } return false; @@ -249,6 +297,7 @@ void cRingBufferFrame::Drop(cFrame *Frame) esyslog("ERROR: attempt to drop wrong frame from ring buffer!"); } Unlock(); + EnablePut(); } int cRingBufferFrame::Available(void) diff --git a/ringbuffer.h b/ringbuffer.h index 6b256627..15063454 100644 --- a/ringbuffer.h +++ b/ringbuffer.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ringbuffer.h 1.11 2003/05/11 09:48:23 kls Exp $ + * $Id: ringbuffer.h 1.12 2003/05/12 17:35:10 kls Exp $ */ #ifndef __RINGBUFFER_H @@ -16,11 +16,19 @@ class cRingBuffer { private: cMutex mutex; + cCondVar readyForPut, readyForGet; + cMutex putMutex, getMutex; + int putTimeout; + int getTimeout; int size; protected: int maxFill;//XXX int lastPercent; bool statistics;//XXX + void WaitForPut(void); + void WaitForGet(void); + void EnablePut(void); + void EnableGet(void); virtual void Clear(void) = 0; virtual int Available(void) = 0; int Free(void) { return size - Available() - 1; } @@ -30,6 +38,7 @@ protected: public: cRingBuffer(int Size, bool Statistics = false); virtual ~cRingBuffer(); + void SetTimeouts(int PutTimeout, int GetTimeout); }; class cRingBufferLinear : public cRingBuffer {