1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Fixed a possible deadlock in cDevice::DetachAllReceivers()

This commit is contained in:
Klaus Schmidinger 2022-01-24 16:53:45 +01:00
parent ea1ad945b4
commit 50c3951017
4 changed files with 23 additions and 8 deletions

View File

@ -3673,6 +3673,7 @@ Helmut Binder <cco@aon.at>
for fixing handling incomplete multi-packet CAT for fixing handling incomplete multi-packet CAT
for fixing a memory leak in handling the NIT for fixing a memory leak in handling the NIT
for reporting a possible memory leak in creating fonts for reporting a possible memory leak in creating fonts
for fixing a possible deadlock in cDevice::DetachAllReceivers()
Ulrich Eckhardt <uli@uli-eckhardt.de> Ulrich Eckhardt <uli@uli-eckhardt.de>
for reporting a problem with shutdown after user inactivity in case a plugin is for reporting a problem with shutdown after user inactivity in case a plugin is

View File

@ -9775,3 +9775,4 @@ Video Disk Recorder Revision History
- Added some missing "AUTO" values to vdr.5 (thanks to Winfried Köhler). - 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 zero bytes in cH264Parser (thanks to Christoph Haubrich).
- Fixed handling error conditions in the index file (reported by Markus Ehrnsperger). - Fixed handling error conditions in the index file (reported by Markus Ehrnsperger).
- Fixed a possible deadlock in cDevice::DetachAllReceivers() (thanks to Helmut Binder).

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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" #include "device.h"
@ -437,6 +437,12 @@ cDevice *cDevice::GetDeviceForTransponder(const cChannel *Channel, int Priority)
return Device; return Device;
} }
void cDevice::ReleaseCamSlot(void)
{
if (camSlot && !camSlot->IsDecrypting() && !camSlot->IsActivating())
camSlot->Assign(NULL);
}
bool cDevice::HasCi(void) bool cDevice::HasCi(void)
{ {
return false; return false;
@ -1823,7 +1829,7 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
return false; return false;
} }
void cDevice::Detach(cReceiver *Receiver) void cDevice::Detach(cReceiver *Receiver, bool ReleaseCam)
{ {
if (!Receiver || Receiver->device != this) if (!Receiver || Receiver->device != this)
return; return;
@ -1845,8 +1851,8 @@ void cDevice::Detach(cReceiver *Receiver)
if (camSlot) { if (camSlot) {
if (Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver if (Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver
camSlot->StartDecrypting(); camSlot->StartDecrypting();
if (!camSlot->IsDecrypting() && !camSlot->IsActivating()) if (ReleaseCam)
camSlot->Assign(NULL); ReleaseCamSlot();
} }
} }
if (!receiversLeft) if (!receiversLeft)
@ -1860,8 +1866,9 @@ void cDevice::DetachAll(int Pid)
for (int i = 0; i < MAXRECEIVERS; i++) { for (int i = 0; i < MAXRECEIVERS; i++) {
cReceiver *Receiver = receiver[i]; cReceiver *Receiver = receiver[i];
if (Receiver && Receiver->WantsPid(Pid)) if (Receiver && Receiver->WantsPid(Pid))
Detach(Receiver); Detach(Receiver, false);
} }
ReleaseCamSlot();
} }
} }
@ -1869,7 +1876,8 @@ void cDevice::DetachAllReceivers(void)
{ {
cMutexLock MutexLock(&mutexReceiver); cMutexLock MutexLock(&mutexReceiver);
for (int i = 0; i < MAXRECEIVERS; i++) for (int i = 0; i < MAXRECEIVERS; i++)
Detach(receiver[i]); Detach(receiver[i], false);
ReleaseCamSlot();
} }
// --- cTSBuffer ------------------------------------------------------------- // --- cTSBuffer -------------------------------------------------------------

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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 #ifndef __DEVICE_H
@ -465,6 +465,8 @@ public:
private: private:
cCamSlot *camSlot; cCamSlot *camSlot;
void ReleaseCamSlot(void);
///< Releases the CAM slot if it is currently not used.
public: public:
virtual bool HasCi(void); virtual bool HasCi(void);
///< Returns true if this device has a Common Interface. ///< 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). ///< Returns true if we are currently receiving. The parameter has no meaning (for backwards compatibility only).
bool AttachReceiver(cReceiver *Receiver); bool AttachReceiver(cReceiver *Receiver);
///< Attaches the given receiver to this device. ///< 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. ///< 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); void DetachAll(int Pid);
///< Detaches all receivers from this device for this pid. ///< Detaches all receivers from this device for this pid.
virtual void DetachAllReceivers(void); virtual void DetachAllReceivers(void);