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

Fixed a possible deadlock when detaching a receiver from a device

This commit is contained in:
Klaus Schmidinger 2017-12-16 13:13:13 +01:00
parent 477fb7dc20
commit 5467bc4f24
2 changed files with 5 additions and 6 deletions

View File

@ -9241,3 +9241,4 @@ Video Disk Recorder Revision History
(suggested by Matthias Senzel). (suggested by Matthias Senzel).
- When selecting a folder for a recording or timer, it is now possible to open a folder - When selecting a folder for a recording or timer, it is now possible to open a folder
even if it doesn't contain any subfolders (suggested by Matthias Senzel). even if it doesn't contain any subfolders (suggested by Matthias Senzel).
- Fixed a possible deadlock when detaching a receiver from a device.

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 4.24 2017/08/31 11:34:54 kls Exp $ * $Id: device.c 4.25 2017/12/16 13:13:13 kls Exp $
*/ */
#include "device.h" #include "device.h"
@ -1673,6 +1673,7 @@ void cDevice::Action(void)
int Pid = TsPid(b); int Pid = TsPid(b);
bool IsScrambled = TsIsScrambled(b); bool IsScrambled = TsIsScrambled(b);
for (int i = 0; i < MAXRECEIVERS; i++) { for (int i = 0; i < MAXRECEIVERS; i++) {
cMutexLock MutexLock(&mutexReceiver);
cReceiver *Receiver = receiver[i]; cReceiver *Receiver = receiver[i];
if (Receiver && Receiver->WantsPid(Pid)) { if (Receiver && Receiver->WantsPid(Pid)) {
Receiver->Receive(b, TS_SIZE); Receiver->Receive(b, TS_SIZE);
@ -1768,10 +1769,8 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
} }
} }
Receiver->Activate(true); Receiver->Activate(true);
Lock();
Receiver->device = this; Receiver->device = this;
receiver[i] = Receiver; receiver[i] = Receiver;
Unlock();
if (camSlot && Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver if (camSlot && Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver
camSlot->StartDecrypting(); camSlot->StartDecrypting();
if (camSlot->WantsTsData()) { if (camSlot->WantsTsData()) {
@ -1801,13 +1800,11 @@ void cDevice::Detach(cReceiver *Receiver)
if (!Receiver || Receiver->device != this) if (!Receiver || Receiver->device != this)
return; return;
bool receiversLeft = false; bool receiversLeft = false;
cMutexLock MutexLock(&mutexReceiver); mutexReceiver.Lock();
for (int i = 0; i < MAXRECEIVERS; i++) { for (int i = 0; i < MAXRECEIVERS; i++) {
if (receiver[i] == Receiver) { if (receiver[i] == Receiver) {
Lock();
receiver[i] = NULL; receiver[i] = NULL;
Receiver->device = NULL; Receiver->device = NULL;
Unlock();
Receiver->Activate(false); Receiver->Activate(false);
for (int n = 0; n < Receiver->numPids; n++) for (int n = 0; n < Receiver->numPids; n++)
DelPid(Receiver->pids[n]); DelPid(Receiver->pids[n]);
@ -1815,6 +1812,7 @@ void cDevice::Detach(cReceiver *Receiver)
else if (receiver[i]) else if (receiver[i])
receiversLeft = true; receiversLeft = true;
} }
mutexReceiver.Unlock();
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();