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