summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2022-01-24 16:53:45 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2022-01-24 16:53:45 +0100
commit50c3951017411eabb5a14f43ccca91cd564f4d3a (patch)
tree5df3fe6f4ed609adb283f5e1c817e2a1ff3eafd1
parentea1ad945b4fdedda8923b88d68d412743845a17e (diff)
downloadvdr-50c3951017411eabb5a14f43ccca91cd564f4d3a.tar.gz
vdr-50c3951017411eabb5a14f43ccca91cd564f4d3a.tar.bz2
Fixed a possible deadlock in cDevice::DetachAllReceivers()
-rw-r--r--CONTRIBUTORS1
-rw-r--r--HISTORY1
-rw-r--r--device.c20
-rw-r--r--device.h9
4 files changed, 23 insertions, 8 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 6a8db43a..eda44d39 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -3673,6 +3673,7 @@ Helmut Binder <cco@aon.at>
for fixing handling incomplete multi-packet CAT
for fixing a memory leak in handling the NIT
for reporting a possible memory leak in creating fonts
+ for fixing a possible deadlock in cDevice::DetachAllReceivers()
Ulrich Eckhardt <uli@uli-eckhardt.de>
for reporting a problem with shutdown after user inactivity in case a plugin is
diff --git a/HISTORY b/HISTORY
index bb560344..99158f26 100644
--- a/HISTORY
+++ b/HISTORY
@@ -9775,3 +9775,4 @@ Video Disk Recorder Revision History
- Added some missing "AUTO" values to vdr.5 (thanks to Winfried Köhler).
- Fixed handling zero bytes in cH264Parser (thanks to Christoph Haubrich).
- Fixed handling error conditions in the index file (reported by Markus Ehrnsperger).
+- Fixed a possible deadlock in cDevice::DetachAllReceivers() (thanks to Helmut Binder).
diff --git a/device.c b/device.c
index fb251cd1..4b9c9cc7 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.c 5.4 2022/01/13 10:56:01 kls Exp $
+ * $Id: device.c 5.5 2022/01/24 16:53:45 kls Exp $
*/
#include "device.h"
@@ -437,6 +437,12 @@ cDevice *cDevice::GetDeviceForTransponder(const cChannel *Channel, int Priority)
return Device;
}
+void cDevice::ReleaseCamSlot(void)
+{
+ if (camSlot && !camSlot->IsDecrypting() && !camSlot->IsActivating())
+ camSlot->Assign(NULL);
+}
+
bool cDevice::HasCi(void)
{
return false;
@@ -1823,7 +1829,7 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
return false;
}
-void cDevice::Detach(cReceiver *Receiver)
+void cDevice::Detach(cReceiver *Receiver, bool ReleaseCam)
{
if (!Receiver || Receiver->device != this)
return;
@@ -1845,8 +1851,8 @@ void cDevice::Detach(cReceiver *Receiver)
if (camSlot) {
if (Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver
camSlot->StartDecrypting();
- if (!camSlot->IsDecrypting() && !camSlot->IsActivating())
- camSlot->Assign(NULL);
+ if (ReleaseCam)
+ ReleaseCamSlot();
}
}
if (!receiversLeft)
@@ -1860,8 +1866,9 @@ void cDevice::DetachAll(int Pid)
for (int i = 0; i < MAXRECEIVERS; i++) {
cReceiver *Receiver = receiver[i];
if (Receiver && Receiver->WantsPid(Pid))
- Detach(Receiver);
+ Detach(Receiver, false);
}
+ ReleaseCamSlot();
}
}
@@ -1869,7 +1876,8 @@ void cDevice::DetachAllReceivers(void)
{
cMutexLock MutexLock(&mutexReceiver);
for (int i = 0; i < MAXRECEIVERS; i++)
- Detach(receiver[i]);
+ Detach(receiver[i], false);
+ ReleaseCamSlot();
}
// --- cTSBuffer -------------------------------------------------------------
diff --git a/device.h b/device.h
index 63eef603..2d0ac12f 100644
--- a/device.h
+++ b/device.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.h 5.1 2021/05/21 12:51:16 kls Exp $
+ * $Id: device.h 5.2 2022/01/24 16:53:45 kls Exp $
*/
#ifndef __DEVICE_H
@@ -465,6 +465,8 @@ public:
private:
cCamSlot *camSlot;
+ void ReleaseCamSlot(void);
+ ///< Releases the CAM slot if it is currently not used.
public:
virtual bool HasCi(void);
///< Returns true if this device has a Common Interface.
@@ -852,8 +854,11 @@ public:
///< Returns true if we are currently receiving. The parameter has no meaning (for backwards compatibility only).
bool AttachReceiver(cReceiver *Receiver);
///< Attaches the given receiver to this device.
- void Detach(cReceiver *Receiver);
+ void Detach(cReceiver *Receiver, bool ReleaseCam = true);
///< Detaches the given receiver from this device.
+ ///< If ReleaseCam is true, the CAM slot will be released if it
+ ///< is no longer used. Otherwise the caller must call ReleaseCamSlot() after
+ ///< calling this function.
void DetachAll(int Pid);
///< Detaches all receivers from this device for this pid.
virtual void DetachAllReceivers(void);