Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] vdr-1.3.18: possible race in start/stop receiver/tsbuffer thread
Hi,
I think that there is a race in how vdr maintains the receiver
and tsbuffer sub-thread.
Both thread are controled by the "active" variable. This variable
is set to true only at the beginning of the sub-thread Action().
If a receiver is attached and immidiately detached (like
streamdev does), the following can happen:
-Receiver attached.
-Receiver and tsbuffer sub-thread launched, but as the time slice
of the current thread may not be used up, their Action(), may be
even their StartThread() functions are not yet processed.
-At this point active is still false.
-Receiver detached.
-Receiver and tsbuffer sub-thread have to be canceled.
-Setting active=false to request sub-thread termination (remember
active is still false and Action() hasn't been processed).
-Calling Cancel() which finaly gives up the time slice in
Active().
-Sub-threads Action() are now executed, setting active=true.
-Termination request slipped away. Sub-thread won't end. Has to
be canceled after timeout.
I'm using the attached patch with vdr-1.3.14 for several weeks.
As the code in vdr-1.3.18 hasn't changed in this area, it should
still be valid.
Regards.
--
Stefan Huelswitt
s.huelswitt@gmx.de | http://www.muempf.de/
diff -u vdr-1.3.18-orig/device.c vdr-current/device.c
--- vdr-1.3.18-orig/device.c 2005-01-09 13:36:48.000000000 +0100
+++ vdr-current/device.c 2005-01-11 22:09:37.000000000 +0100
@@ -990,8 +992,7 @@
void cDevice::Action(void)
{
- active = true;
- if (OpenDvr()) {
+ if (active && OpenDvr()) {
for (; active;) {
// Read data from the DVR device:
uchar *b = NULL;
@@ -1053,7 +1074,10 @@
Receiver->device = this;
receiver[i] = Receiver;
Unlock();
- Start();
+ if(!active) {
+ active = true;
+ Start();
+ }
return true;
}
}
@@ -1093,10 +1117,10 @@
SetDescription("TS buffer on device %d", CardIndex);
f = File;
cardIndex = CardIndex;
- active = false;
delivered = false;
ringBuffer = new cRingBufferLinear(Size, TS_SIZE, true, "TS");
ringBuffer->SetTimeouts(100, 100);
+ active = true;
Start();
}
@@ -1112,7 +1136,6 @@
if (ringBuffer) {
bool firstRead = true;
cPoller Poller(f);
- active = true;
for (; active;) {
if (firstRead || Poller.Poll(100)) {
firstRead = false;
Home |
Main Index |
Thread Index