[PATCH] Add thread safety to cRingBufferLinear

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Beside preventing crashes with vdr-2.6.3 this is required to
get vdr to work properly with the gcc thread sanitizer.
---
 ringbuffer.c | 18 +++++++++++++++++-
 ringbuffer.h |  3 +++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/ringbuffer.c b/ringbuffer.c
index 902c887..1c24df2 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -210,12 +210,16 @@ int cRingBufferLinear::DataReady(const uchar *Data, int Count)
 
 int cRingBufferLinear::Available(void)
 {
+  Lock();
   int diff = head - tail;
-  return (diff >= 0) ? diff : Size() + diff - margin;
+  int available = (diff >= 0) ? diff : Size() + diff - margin;
+  Unlock();
+  return available;
 }
 
 void cRingBufferLinear::Clear(void)
 {
+  Lock();
   int Head = head;
   tail = Head;
 #ifdef DEBUGRINGBUFFERS
@@ -224,11 +228,13 @@ void cRingBufferLinear::Clear(void)
   lastPut = lastGet = -1;
 #endif
   maxFill = 0;
+  Unlock();
   EnablePut();
 }
 
 int cRingBufferLinear::Read(int FileHandle, int Max)
 {
+  Lock();
   int Tail = tail;
   int diff = Tail - head;
   int free = (diff > 0) ? diff - 1 : Size() - head;
@@ -259,6 +265,7 @@ int cRingBufferLinear::Read(int FileHandle, int Max)
   lastHead = head;
   lastPut = Count;
 #endif
+  Unlock();
   EnableGet();
   if (free == 0)
      WaitForPut();
@@ -267,6 +274,7 @@ int cRingBufferLinear::Read(int FileHandle, int Max)
 
 int cRingBufferLinear::Read(cUnbufferedFile *File, int Max)
 {
+  Lock();
   int Tail = tail;
   int diff = Tail - head;
   int free = (diff > 0) ? diff - 1 : Size() - head;
@@ -297,6 +305,7 @@ int cRingBufferLinear::Read(cUnbufferedFile *File, int Max)
   lastHead = head;
   lastPut = Count;
 #endif
+  Unlock();
   EnableGet();
   if (free == 0)
      WaitForPut();
@@ -306,6 +315,7 @@ int cRingBufferLinear::Read(cUnbufferedFile *File, int Max)
 int cRingBufferLinear::Put(const uchar *Data, int Count)
 {
   if (Count > 0) {
+     Lock();
      int Tail = tail;
      int rest = Size() - head;
      int diff = Tail - head;
@@ -336,6 +346,7 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
      lastHead = head;
      lastPut = Count;
 #endif
+     Unlock();
      EnableGet();
      if (Count == 0)
         WaitForPut();
@@ -345,6 +356,7 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
 
 uchar *cRingBufferLinear::Get(int &Count)
 {
+  Lock();
   int Head = head;
   if (getThreadTid <= 0)
      getThreadTid = cThread::ThreadId();
@@ -362,14 +374,17 @@ uchar *cRingBufferLinear::Get(int &Count)
   uchar *p = buffer + tail;
   if ((cont = DataReady(p, cont)) > 0) {
      Count = gotten = cont;
+     Unlock();
      return p;
      }
+  Unlock();
   WaitForGet();
   return NULL;
 }
 
 void cRingBufferLinear::Del(int Count)
 {
+  Lock();
   if (Count > gotten) {
      esyslog("ERROR: invalid Count in cRingBufferLinear::Del: %d (limited to %d)", Count, gotten);
      Count = gotten;
@@ -387,6 +402,7 @@ void cRingBufferLinear::Del(int Count)
   lastTail = tail;
   lastGet = Count;
 #endif
+  Unlock();
 }
 
 // --- cFrame ----------------------------------------------------------------
diff --git a/ringbuffer.h b/ringbuffer.h
index 746fc51..cbaa12c 100644
--- a/ringbuffer.h
+++ b/ringbuffer.h
@@ -58,10 +58,13 @@ public:
   static void PrintDebugRBL(void);
 #endif
 private:
+  cMutex mutex;
   int margin, head, tail;
   int gotten;
   uchar *buffer;
   char *description;
+  void Lock(void) { mutex.Lock(); }
+  void Unlock(void) { mutex.Unlock(); }
 protected:
   virtual int DataReady(const uchar *Data, int Count);
     ///< By default a ring buffer has data ready as soon as there are at least
-- 
2.39.1


_______________________________________________
vdr mailing list
vdr@xxxxxxxxxxx
https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr



[Index of Archives]     [Linux Media]     [Asterisk]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Big List of Linux Books]     [Fedora Users]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux