mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Improved thread locking in the ring buffer to avoid possible race conditions under heavy load
This commit is contained in:
parent
849ec98c3d
commit
8ec5c0d926
@ -157,6 +157,8 @@ Werner Fink <werner@suse.de>
|
|||||||
for helping to debug leftover 'zombie' processes when closing a pipe
|
for helping to debug leftover 'zombie' processes when closing a pipe
|
||||||
for making the Dolby Digital thread start only if the recording actually
|
for making the Dolby Digital thread start only if the recording actually
|
||||||
contains Dolby Digital data
|
contains Dolby Digital data
|
||||||
|
for improving thread locking in the ring buffer to avoid possible race conditions
|
||||||
|
under heavy load
|
||||||
|
|
||||||
Rolf Hakenes <hakenes@hippomi.de>
|
Rolf Hakenes <hakenes@hippomi.de>
|
||||||
for providing 'libdtv' and adapting the EIT mechanisms to it
|
for providing 'libdtv' and adapting the EIT mechanisms to it
|
||||||
|
4
HISTORY
4
HISTORY
@ -1191,7 +1191,7 @@ Video Disk Recorder Revision History
|
|||||||
same name was manually deleted on a system with more than one video directory
|
same name was manually deleted on a system with more than one video directory
|
||||||
(thanks to Dirk Wiebel for reporting this one).
|
(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
|
- Added some DVB-T channels for Berlin (Germany) to channels.conf.terr (thanks to
|
||||||
Andreas Roedl).
|
Andreas Roedl).
|
||||||
@ -1204,3 +1204,5 @@ Video Disk Recorder Revision History
|
|||||||
any timers referencing a channel with a number higher than 102 should be
|
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
|
checked and adapted if necessary (this only applies if you are using the default
|
||||||
'channels.conf').
|
'channels.conf').
|
||||||
|
- Improved thread locking in the ring buffer to avoid possible race conditions
|
||||||
|
under heavy load (thanks to Werner Fink).
|
||||||
|
66
ringbuffer.c
66
ringbuffer.c
@ -7,7 +7,7 @@
|
|||||||
* Parts of this file were inspired by the 'ringbuffy.c' from the
|
* Parts of this file were inspired by the 'ringbuffy.c' from the
|
||||||
* LinuxDVB driver (see linuxtv.org).
|
* 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"
|
#include "ringbuffer.h"
|
||||||
@ -154,7 +154,6 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
|
|||||||
Lock();
|
Lock();
|
||||||
int rest = Size() - head;
|
int rest = Size() - head;
|
||||||
int diff = tail - head;
|
int diff = tail - head;
|
||||||
Unlock();
|
|
||||||
int free = (diff > 0) ? diff - 1 : Size() + diff - 1;
|
int free = (diff > 0) ? diff - 1 : Size() + diff - 1;
|
||||||
if (statistics) {
|
if (statistics) {
|
||||||
int fill = Size() - free - 1 + Count;
|
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);
|
dsyslog(LOG_INFO, "buffer usage: %d%%", percent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (free <= 0)
|
if (free > 0) {
|
||||||
return 0;
|
if (free < Count)
|
||||||
if (free < Count)
|
Count = free;
|
||||||
Count = free;
|
if (Count > maxFill)
|
||||||
if (Count > maxFill)
|
maxFill = Count;
|
||||||
maxFill = Count;
|
if (Count >= rest) {
|
||||||
if (Count >= rest) {
|
memcpy(buffer + head, Data, rest);
|
||||||
memcpy(buffer + head, Data, rest);
|
if (Count - rest)
|
||||||
if (Count - rest)
|
memcpy(buffer, Data + rest, Count - rest);
|
||||||
memcpy(buffer, Data + rest, Count - rest);
|
head = Count - rest;
|
||||||
head = Count - rest;
|
}
|
||||||
}
|
else {
|
||||||
else {
|
memcpy(buffer + head, Data, Count);
|
||||||
memcpy(buffer + head, Data, Count);
|
head += Count;
|
||||||
head += Count;
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Count = 0;
|
||||||
|
Unlock();
|
||||||
}
|
}
|
||||||
return Count;
|
return Count;
|
||||||
}
|
}
|
||||||
@ -193,22 +195,24 @@ int cRingBufferLinear::Get(uchar *Data, int Count)
|
|||||||
Lock();
|
Lock();
|
||||||
int rest = Size() - tail;
|
int rest = Size() - tail;
|
||||||
int diff = head - tail;
|
int diff = head - tail;
|
||||||
Unlock();
|
|
||||||
int cont = (diff >= 0) ? diff : Size() + diff;
|
int cont = (diff >= 0) ? diff : Size() + diff;
|
||||||
if (rest <= 0)
|
if (rest > 0) {
|
||||||
return 0;
|
if (cont < Count)
|
||||||
if (cont < Count)
|
Count = cont;
|
||||||
Count = cont;
|
if (Count >= rest) {
|
||||||
if (Count >= rest) {
|
memcpy(Data, buffer + tail, rest);
|
||||||
memcpy(Data, buffer + tail, rest);
|
if (Count - rest)
|
||||||
if (Count - rest)
|
memcpy(Data + rest, buffer, Count - rest);
|
||||||
memcpy(Data + rest, buffer, Count - rest);
|
tail = Count - rest;
|
||||||
tail = Count - rest;
|
}
|
||||||
}
|
else {
|
||||||
else {
|
memcpy(Data, buffer + tail, Count);
|
||||||
memcpy(Data, buffer + tail, Count);
|
tail += Count;
|
||||||
tail += Count;
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Count = 0;
|
||||||
|
Unlock();
|
||||||
}
|
}
|
||||||
return Count;
|
return Count;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user