From 8ec5c0d9268a5f1194d7aea704f289a0e1004af1 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Fri, 19 Apr 2002 12:40:04 +0200 Subject: [PATCH] Improved thread locking in the ring buffer to avoid possible race conditions under heavy load --- CONTRIBUTORS | 2 ++ HISTORY | 4 +++- ringbuffer.c | 66 ++++++++++++++++++++++++++++------------------------ 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 88f997ce..bff993cf 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -157,6 +157,8 @@ Werner Fink for helping to debug leftover 'zombie' processes when closing a pipe for making the Dolby Digital thread start only if the recording actually contains Dolby Digital data + for improving thread locking in the ring buffer to avoid possible race conditions + under heavy load Rolf Hakenes for providing 'libdtv' and adapting the EIT mechanisms to it diff --git a/HISTORY b/HISTORY index e2d69225..49d94a05 100644 --- a/HISTORY +++ b/HISTORY @@ -1191,7 +1191,7 @@ Video Disk Recorder Revision History same name was manually deleted on a system with more than one video directory (thanks to Dirk Wiebel for reporting this one). -2002-04-13: Version 1.0.1 +2002-04-19: Version 1.0.1 - Added some DVB-T channels for Berlin (Germany) to channels.conf.terr (thanks to Andreas Roedl). @@ -1204,3 +1204,5 @@ Video Disk Recorder Revision History any timers referencing a channel with a number higher than 102 should be checked and adapted if necessary (this only applies if you are using the default 'channels.conf'). +- Improved thread locking in the ring buffer to avoid possible race conditions + under heavy load (thanks to Werner Fink). diff --git a/ringbuffer.c b/ringbuffer.c index 8b8420c1..88b515b4 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.5 2001/11/03 09:50:46 kls Exp $ + * $Id: ringbuffer.c 1.6 2002/04/19 12:38:44 kls Exp $ */ #include "ringbuffer.h" @@ -154,7 +154,6 @@ int cRingBufferLinear::Put(const uchar *Data, int Count) Lock(); int rest = Size() - head; int diff = tail - head; - Unlock(); int free = (diff > 0) ? diff - 1 : Size() + diff - 1; if (statistics) { int fill = Size() - free - 1 + Count; @@ -167,22 +166,25 @@ int cRingBufferLinear::Put(const uchar *Data, int Count) 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; + if (free > 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; + } } + else + Count = 0; + Unlock(); } return Count; } @@ -193,22 +195,24 @@ int cRingBufferLinear::Get(uchar *Data, int Count) Lock(); int rest = Size() - tail; int diff = head - tail; - 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; + if (rest > 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; + } } + else + Count = 0; + Unlock(); } return Count; }